This is a cleaned version of 04_24_19 Temp link trait fish.Rmd/11_20_19_Temp_link_traits_fish.Rmd. Changes * improved formatting * easier to follow * species and region as random effects * scaling temperature values * setting nACQ to 0, see why here.

library(MuMIn)
library(lme4)
library(data.table)
library(ggplot2)
library(here)
library(wesanderson) # to color plots

readRDS(here("Data","Spp_master", "spp_master_ztemp_seus_buoy_scaled.rds"))

Running, and ranking arrival models without traits

##Here, I scaled all temperature values across all regions, and included species as a random effect. In order to do this, I had to change the algorithm slightly–nAGQ = 0.

#names of scaled columns
variables_scaled <- grep("*_scaled", names(spp_master_ztemp_seus_buoy_scaled), value = T)

#going to make loop to make all models I need to look at with a single temperature variable

arrival_model_comparison <- as.data.table(matrix(nrow = length(variables_scaled)))
arrival_model_comparison[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
arrival_model_comparison[, V1 := NULL]

for (i in 1:length(variables_scaled)){
  mod <- glmer(col ~ get(variables_scaled[i]) + (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled, nAGQ = 0)
  arrival_model_comparison[i,variable := variables_scaled[i]]
  arrival_model_comparison[i,coef := coef(summary(mod))[,"Estimate"][2]]
  arrival_model_comparison[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
  arrival_model_comparison[i,AICc := AICc(mod)]
  
  print(paste(i, length(variables_scaled), sep = "/"))
    
}

#by setting nACQ to 0, all models converged

saveRDS(object = arrival_model_comparison, file = here("Model_results","arrival_model_results.rds"))
arrival_model_comparison <- readRDS(here("Model_results","arrival_model_results.rds"))

Departure Models without Traits


departure_model_comparison <- as.data.table(matrix(nrow = length(variables_scaled)))
departure_model_comparison[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
departure_model_comparison[, V1 := NULL]

for (i in 1:length(variables_scaled)){
  mod <- glmer(now_ext ~ get(variables_scaled[i]) + (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled, nAGQ = 0)
  departure_model_comparison[i,variable := variables_scaled[i]]
  departure_model_comparison[i,coef := coef(summary(mod))[,"Estimate"][2]]
  departure_model_comparison[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
  departure_model_comparison[i,AICc := AICc(mod)]
  
  print(paste(i, length(variables_scaled), sep = "/"))
    
}

#by setting nACQ to 0, all models converged

saveRDS(object = departure_model_comparison, file = here("Model_results","departure_model_results.rds"))
departure_model_comparison <- readRDS(here("Model_results","departure_model_results.rds"))

Relative Variable Importance

NB: I didn’t end up using mean as a predictor variable (patterns captured in min and max, less relevant to thermal niche)

arrival_model_comparison_nomean <- arrival_model_comparison[!grepl("mean",variable),]

departure_model_comparison_nomean <- departure_model_comparison[!grepl("mean",variable),]

How does the null model with only random effects perform?

#add null to tables
intercept_arrival_mod_scaled <- glmer(col ~ (1|spp) + (1|reg), family = binomial, nAGQ = 0, data = spp_master_ztemp_seus_buoy_scaled)

intercept_departure_mod_scaled <- glmer(now_ext ~ (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled, nAGQ = 0)

#best model better than null? yes
AICc(intercept_arrival_mod_scaled)-min(arrival_model_comparison$AICc)
AICc(intercept_departure_mod_scaled)-min(departure_model_comparison$AICc)

Relative Variable Importance for Arrival Models

Relative Variable Importance for different Pairs of Transformation and Metric


#I want to look at relative importance FOR 
#models with raw and min
arrival_raw_min_importance <- sum(arrival_model_comparison_nomean[grep("min", variable), ][!grep("change", variable)]$akaike_weight)

#models with raw and max
arrival_raw_max_importance <- sum(arrival_model_comparison_nomean[grep("max", variable), ][!grep("change", variable)]$akaike_weight)

#models with raw and seas
arrival_raw_seas_importance <- sum(arrival_model_comparison_nomean[grep("seas", variable), ][!grep("change", variable)]$akaike_weight)


#models with change and min
arrival_change_min_importance <- sum(arrival_model_comparison_nomean[grep("min_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with change and max
arrival_change_max_importance <- sum(arrival_model_comparison_nomean[grep("max_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with change and seas
arrival_change_seas_importance <- sum(arrival_model_comparison_nomean[grep("seas_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with abs change and min
arrival_abs_change_min_importance <- sum(arrival_model_comparison_nomean[grep("min_s.t_temp_change_abs", variable), ]$akaike_weight)

#models with abs change and max
arrival_abs_change_max_importance <- sum(arrival_model_comparison_nomean[grep("max_s.t_temp_change_abs", variable), ]$akaike_weight)

#models with abs change and seas
arrival_abs_change_seas_importance <- sum(arrival_model_comparison_nomean[grep("seas_s.t_temp_change_abs", variable), ]$akaike_weight)

arrival_transform_metric_comparison <- data.table(Transformation =
                                                c("raw", "raw", "raw", "change", "change", "change", "abs_change", "abs_change", "abs_change"), 
                                              Metric = 
                                                rep(c("min", "max", "seas"), 3), 
                                              RVI = 
                                                c(arrival_raw_min_importance, arrival_raw_max_importance, 
                                                  arrival_raw_seas_importance, arrival_change_min_importance, 
                                                  arrival_change_max_importance, arrival_change_seas_importance, 
                                                  arrival_abs_change_min_importance, arrival_abs_change_max_importance, 
                                                  arrival_abs_change_seas_importance))

Relative Variable Importance Departure Models

Relative Variable Importance for Pairs of Transformation and Metric Predicting departures


#I want to look at relative importance FOR 
#models with raw and min
departure_raw_min_importance <- sum(departure_model_comparison_nomean[grep("min", variable), ][!grep("change", variable)]$akaike_weight)

#models with raw and max
departure_raw_max_importance <- sum(departure_model_comparison_nomean[grep("max", variable), ][!grep("change", variable)]$akaike_weight)

#models with raw and seas
departure_raw_seas_importance <- sum(departure_model_comparison_nomean[grep("seas", variable), ][!grep("change", variable)]$akaike_weight)


#models with change and min
departure_change_min_importance <- sum(departure_model_comparison_nomean[grep("min_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with change and max
departure_change_max_importance <- sum(departure_model_comparison_nomean[grep("max_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with change and seas
departure_change_seas_importance <- sum(departure_model_comparison_nomean[grep("seas_s.t_temp_change", variable), ][!grep("abs", variable)]$akaike_weight)

#models with abs change and min
departure_abs_change_min_importance <- sum(departure_model_comparison_nomean[grep("min_s.t_temp_change_abs", variable), ]$akaike_weight)

#models with abs change and max
departure_abs_change_max_importance <- sum(departure_model_comparison_nomean[grep("max_s.t_temp_change_abs", variable), ]$akaike_weight)

#models with abs change and seas
departure_abs_change_seas_importance <- sum(departure_model_comparison_nomean[grep("seas_s.t_temp_change_abs", variable), ]$akaike_weight)

departure_transform_metric_comparison <- data.table(Transformation =
                                                c("raw", "raw", "raw", "change", "change", "change", "abs_change", "abs_change", "abs_change"), 
                                              Metric = 
                                                rep(c("min", "max", "seas"), 3), 
                                              RVI = 
                                                c(departure_raw_min_importance, departure_raw_max_importance, 
                                                  departure_raw_seas_importance, departure_change_min_importance, 
                                                  departure_change_max_importance, departure_change_seas_importance, 
                                                  departure_abs_change_min_importance, departure_abs_change_max_importance, 
                                                  departure_abs_change_seas_importance))

Let’s see how the RVI importance varies by looking at specific lag values


#first, table for lags
lags_RVI_scaled <- data.table(arrival_lag = c(0:9), arrival_RVI = 0, departure_RVI = 0)

#arrivals
lags_RVI_scaled[1,2] <- 1-sum(arrival_model_comparison_nomean[grep("lag", variable), ]$akaike_weight)
lags_RVI_scaled[2,2] <- sum(arrival_model_comparison_nomean[grep("lag1", variable), ]$akaike_weight)
lags_RVI_scaled[3,2] <- sum(arrival_model_comparison_nomean[grep("lag2", variable), ]$akaike_weight)
lags_RVI_scaled[4,2] <- sum(arrival_model_comparison_nomean[grep("lag3", variable), ]$akaike_weight)
lags_RVI_scaled[5,2] <- sum(arrival_model_comparison_nomean[grep("lag4", variable), ]$akaike_weight)
lags_RVI_scaled[6,2] <- sum(arrival_model_comparison_nomean[grep("lag5", variable), ]$akaike_weight)
lags_RVI_scaled[7,2] <- sum(arrival_model_comparison_nomean[grep("lag6", variable), ]$akaike_weight)
lags_RVI_scaled[8,2] <- sum(arrival_model_comparison_nomean[grep("lag7", variable), ]$akaike_weight)
lags_RVI_scaled[9,2] <- sum(arrival_model_comparison_nomean[grep("lag8", variable), ]$akaike_weight)
lags_RVI_scaled[10,2] <- sum(arrival_model_comparison_nomean[grep("lag9", variable), ]$akaike_weight)

#departures
lags_RVI_scaled[1,3] <- 1-sum(departure_model_comparison_nomean[grep("lag", variable), ]$akaike_weight)
lags_RVI_scaled[2,3] <- sum(departure_model_comparison_nomean[grep("lag1", variable), ]$akaike_weight)
lags_RVI_scaled[3,3] <- sum(departure_model_comparison_nomean[grep("lag2", variable), ]$akaike_weight)
lags_RVI_scaled[4,3] <- sum(departure_model_comparison_nomean[grep("lag3", variable), ]$akaike_weight)
lags_RVI_scaled[5,3] <- sum(departure_model_comparison_nomean[grep("lag4", variable), ]$akaike_weight)
lags_RVI_scaled[6,3] <- sum(departure_model_comparison_nomean[grep("lag5", variable), ]$akaike_weight)
lags_RVI_scaled[7,3] <- sum(departure_model_comparison_nomean[grep("lag6", variable), ]$akaike_weight)
lags_RVI_scaled[8,3] <- sum(departure_model_comparison_nomean[grep("lag7", variable), ]$akaike_weight)
lags_RVI_scaled[9,3] <- sum(departure_model_comparison_nomean[grep("lag8", variable), ]$akaike_weight)
lags_RVI_scaled[10,3] <- sum(departure_model_comparison_nomean[grep("lag9", variable), ]$akaike_weight)

saveRDS(lags_RVI_scaled, here("Model_results","lags_RVI_scaled.rds"))

#visualize lags through time
ggplot(data = lags_RVI_scaled, aes(x = arrival_lag)) +
  geom_line(aes(y = arrival_RVI), ) +
  geom_line(aes(y = departure_RVI), linetype = "dashed") +
  labs(x = "Lag (years)", y = "Relative Variable Importance") +
  scale_color_discrete() + #how to make a legend
  theme_classic() +
  theme(text = element_text(size = 20)) +
  scale_x_continuous(breaks = c(0:9))

Table for RVI data for arrival

arrival_departure <- c("arrival","arrival","arrival","arrival","arrival", "arrival","arrival", "arrival", "arrival","arrival","arrival","arrival","arrival","arrival", "arrival","arrival", "arrival", "arrival","arrival")
type <- c("Depth", "Depth", "lag", "lag", "Transformation", "Transformation", "Transformation", "Metric", "Metric", "Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric")
variable <- c("Bottom", "Surface", "no_lag", "lagged", "|Change|", "Change", "Raw", "Min", "Max", "Seas", "Raw x Min", "Raw x Max", "Raw x Seas", "Change x Min", "Change x Max", "Change x Seas", "|Change| x Min", "|Change| x Max", "|Change| x Seas")


value <- c(arrival_bottom_importance, arrival_surface_importance, arrival_nolag_importance, arrival_lag_importance, arrival_abs_importance, arrival_change_importance, arrival_raw_importance, arrival_min_temp_importance, arrival_max_temp_importance, arrival_seas_temp_importance, arrival_raw_min_importance, arrival_raw_max_importance, arrival_raw_seas_importance, arrival_change_min_importance, arrival_change_max_importance, arrival_change_seas_importance, arrival_abs_change_min_importance, arrival_abs_change_max_importance, arrival_abs_change_seas_importance)

RVI_arrival <- data.table(arrival_departure, type, variable, value)

Table for RVI data for departure

arrival_departure <- c("departure","departure","departure","departure","departure", "departure","departure", "departure", "departure","departure","departure","departure","departure","departure", "departure","departure", "departure", "departure","departure")
type <- c("Depth", "Depth", "lag", "lag", "Transformation", "Transformation", "Transformation", "Metric", "Metric", "Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric", "Transformation x Metric")
variable <- c("Bottom", "Surface", "no_lag", "lagged", "|Change|", "Change", "Raw", "Min", "Max", "Seas", "Raw x Min", "Raw x Max", "Raw x Seas", "Change x Min", "Change x Max", "Change x Seas", "|Change| x Min", "|Change| x Max", "|Change| x Seas")
value <- c(departure_bottom_importance, departure_surface_importance, departure_nolag_importance, departure_lag_importance, departure_abs_importance, departure_change_importance, departure_raw_importance, departure_min_temp_importance, departure_max_temp_importance, departure_seas_temp_importance, departure_raw_min_importance, departure_raw_max_importance, departure_raw_seas_importance, departure_change_min_importance, departure_change_max_importance, departure_change_seas_importance, departure_abs_change_min_importance, departure_abs_change_max_importance, departure_abs_change_seas_importance)

RVI_departure <- data.table(arrival_departure, type, variable, value)

Merge RVI tables for arrival and departure, and then graph

RVI_table <- as.data.table(rbind(RVI_arrival, RVI_departure)) #bind RVI for arrivals and departures

RVI_table.r <- RVI_table[!grep("Surface", variable)][!grep("lagged", variable)]

#change order of factor levels
RVI_table.r[, variable := factor(variable, levels = c("Bottom", "no_lag", "Raw", "Change", "|Change|", "Min", "Max", "Seas"))]

saveRDS(RVI_table, file = here("Model_results", "RVI_table.rds"))

ggplot(data = RVI_table.r, aes(x=variable, y = value, fill = arrival_departure)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_x_discrete(breaks = c("Bottom", "no_lag", "Raw", "Change", "|Change|", "Min", "Max", "Seas"), 
                   labels = c("Bottom Temp", "No Lag", "Raw Temp", "Change in \nTemp", "| Change in\n Temp |", "Min Temp", "Max Temp", "Seas")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance")  +
  theme_bw()

Another way to visualize is stacked bar plot.

#put levels into correct order for viewing, and add dummy level for legend
RVI_arrival[, variable := factor(variable, levels = c("Bottom", "Surface","  ", "Raw", "Change", "|Change|", "no_lag", "lagged", "Min", "Max", "Seas"))]
RVI_arrival[, type := factor(type, levels = c("Depth", "Transformation", "Metric", "lag"))]

RVI_arrival_nolag <- RVI_arrival[type != "lag",]
RVI_arrival_nolag[, type := factor(type, levels = c("Depth", "Transformation", "Metric"))][, variable := factor(variable, levels = c("Bottom", "Surface","  ", "Raw", "Change", "|Change|", "Min", "Max", "Seas"))]

saveRDS(RVI_arrival_nolag, here("Model_results", "RVI_arrival_nolag.rds"))

#and again for departure
RVI_departure[, variable := factor(variable, levels = c("Bottom", "Surface","  ", "Raw", "Change", "|Change|", "no_lag", "lagged", "Min", "Max", "Seas"))]
RVI_departure[, type := factor(type, levels = c("Depth", "Transformation", "Metric", "lag"))]

RVI_departure_nolag <- RVI_departure[type != "lag",]
RVI_departure_nolag[, type := factor(type, levels = c("Depth", "Transformation", "Metric"))][, variable := factor(variable, levels = c("Bottom", "Surface","  ", "Raw", "Change", "|Change|", "Min", "Max", "Seas"))]

saveRDS(RVI_departure_nolag, here("Model_results", "RVI_departure_nolag.rds"))


#plotting
pal <- wes_palette("GrandBudapest1", 8, type = "continuous")
colors <- c(pal[1], pal[2], "#FFFFFF", pal[3], pal[4], pal[5], pal[6], pal[7], pal[8])

#arrivals
RVI_arrival_plot <- ggplot(data = RVI_arrival_nolag, aes(x=type, y = value, fill = variable)) +
  geom_bar(stat="identity", color = "black", size = 0, width = 0.8) +
  scale_x_discrete(breaks = c("Depth", "Transformation", "Metric"), labels = c("Depth", "Transformation", "Metric")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance") +
  theme_classic() +
  theme(text = element_text(size = 11.5), 
        legend.position = "top", 
        legend.title = element_blank(), 
        legend.spacing.x = unit(0.2, 'cm'),
        legend.justification = "center",
        aspect.ratio = (1),
        #, legend.position = "none"
        ) +
  guides(fill=guide_legend(ncol=3)) +
  scale_fill_manual(values = colors,
                    drop = F)

#departure
RVI_departure_plot <- ggplot(data = RVI_departure_nolag, aes(x=type, y = value, fill = variable)) +
  geom_bar(stat="identity", color = "black", size = 0, width = 0.8) +
  scale_x_discrete(breaks = c("Depth", "Transformation", "Metric"), labels = c("Depth", "Transformation", "Metric")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance") +
  theme_classic() +
  theme(text = element_text(size = 11.5), 
        legend.position = "top", 
        legend.title = element_blank(), 
        legend.spacing.x = unit(0.2, 'cm'),
        legend.justification = "center",
        aspect.ratio = (1),
        #, legend.position = "none"
        ) +
  guides(fill=guide_legend(ncol=3)) +
  scale_fill_manual(values = colors,
                    drop = F)

RVI_table
RVI_arrival_plot
RVI_departure_plot

Next step is to add the coefficients on to the bar chart. To do this, I will need to sum (aikake weight of model including variable x coefficient). I think this will be easy enough Using arrival_model_comparison_nomean data frame. I will add new column to data frame of aikaike weight x coefficient

#for some reason the coefficient is a factor
arrival_model_comparison_nomean[,coef_num := as.numeric(as.character(coef))]
arrival_model_comparison_nomean[,aw_coef := akaike_weight * coef_num]

#bottom temperature avg coefficient
arrival_bottom_temp_avg_coef <- sum(arrival_model_comparison_nomean[grep("sbt", variable)]$coef_num)

#surface temperature avg coefficient
arrival_surface_temp_avg_coef <- sum(arrival_model_comparison_nomean[grep("sst", variable)]$coef_num)

#raw seasonality avg coefficient
arrival_seas_raw_avg_coef <- 
  sum(arrival_model_comparison_nomean[grep("seas", variable), ][!grep("change", variable)]$coef_num)

#max abs change avg coefficient
arrival_max_abs_change_avg_coef <- 
  sum(arrival_model_comparison_nomean[grep("max_s.t_temp_change_abs", variable), ]$coef_num)
#for some reason the coefficient is a factor
departure_model_comparison_nomean[,coef_num := as.numeric(as.character(coef))]
departure_model_comparison_nomean[,aw_coef := akaike_weight * coef_num]

#bottom temperature avg coefficient
departure_bottom_temp_avg_coef <- sum(departure_model_comparison_nomean[grep("sbt", variable)]$coef_num)

#surface temperature avg coefficient
departure_surface_temp_avg_coef <- sum(departure_model_comparison_nomean[grep("sst", variable)]$coef_num)

#raw seasonality avg coefficient
departure_seas_raw_avg_coef <- 
  sum(departure_model_comparison_nomean[grep("seas", variable), ][!grep("change", variable)]$coef_num)

#min change avg coefficient
departure_min_abs_change_avg_coef <- 
  sum(departure_model_comparison_nomean[grep("min_s.t_temp_change", variable), ][!grep("abs", variable)]$coef_num)

#seas change avg coefficient
departure_seas_change_avg_coef <- 
  sum(departure_model_comparison_nomean[grep("seas_s.t_temp_change", variable), ][!grep("abs", variable)]$coef_num)

##What if we run these models with fish only? No traits? How do inverts change the story? Because it looks like above, not a ton of invertebrates are going in and out.

#list of fish names from trait database
traits <- fread("TraitCollectionFishNAtlanticNEPacificContShelf (3).csv")

#make fish no fish key
fish <- data.table(spp = unique(traits$taxon), fish = "Y")

#combine with spp master
spp_master_ztemp_seus_buoy_scaled_fishonly <- merge(spp_master_ztemp_seus_buoy_scaled, fish, all.x = T)

#get rid of any rows that aren't observations of fish
spp_master_ztemp_seus_buoy_scaled_fishonly2 <- spp_master_ztemp_seus_buoy_scaled_fishonly[fish == "Y",]

Running models for fish only


#names of scaled columns
scaled_cols <- grep("*_scaled", names(spp_master_ztemp_seus_buoy_scaled_fishonly2), value = T)

#going to make loop to make all models I need to look at with single variables
variables_scaled <- colnames(spp_master_ztemp_seus_buoy_scaled_fishonly2[,scaled_cols, with = FALSE])

arrival_model_comparison_spprandom_scaled_seus_update_fishonly <- as.data.table(matrix(nrow = length(variables_scaled)))
arrival_model_comparison_spprandom_scaled_seus_update_fishonly[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
arrival_model_comparison_spprandom_scaled_seus_update_fishonly[, V1 := NULL]

for (i in 1:length(variables_scaled)){
  mod <- glmer(col ~ get(variables_scaled[i]) + (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled_fishonly2, nAGQ = 0)
  arrival_model_comparison_spprandom_scaled_seus_update_fishonly[i,variable := variables_scaled[i]]
  arrival_model_comparison_spprandom_scaled_seus_update_fishonly[i,coef := coef(summary(mod))[,"Estimate"][2]]
  arrival_model_comparison_spprandom_scaled_seus_update_fishonly[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
  arrival_model_comparison_spprandom_scaled_seus_update_fishonly[i,AICc := AICc(mod)]
  
  print(paste(i, length(variables_scaled), sep = "/"))
    
}

#by setting nACQ to 0, all models converged

departure Models without Traits

#see setup above

departure_model_comparison_spprandom_scaled_seus_update_fishonly <- as.data.table(matrix(nrow = length(variables_scaled)))
departure_model_comparison_spprandom_scaled_seus_update_fishonly[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
departure_model_comparison_spprandom_scaled_seus_update_fishonly[, V1 := NULL]

for (i in 1:length(variables_scaled)){
  mod <- glmer(now_ext ~ get(variables_scaled[i]) + (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled_fishonly2, nAGQ = 0)
  departure_model_comparison_spprandom_scaled_seus_update_fishonly[i,variable := variables_scaled[i]]
  departure_model_comparison_spprandom_scaled_seus_update_fishonly[i,coef := coef(summary(mod))[,"Estimate"][2]]
  departure_model_comparison_spprandom_scaled_seus_update_fishonly[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
  departure_model_comparison_spprandom_scaled_seus_update_fishonly[i,AICc := AICc(mod)]
  
  print(paste(i, length(variables_scaled), sep = "/"))
    
}

#by setting nACQ to 0, all models converged

Relative Variable Importance

arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean <- arrival_model_comparison_spprandom_scaled_seus_update_fishonly[!grepl("mean",variable),]

departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean <- departure_model_comparison_spprandom_scaled_seus_update_fishonly[!grepl("mean",variable),]

#comparison to null
col_mod_null <- glmer(col ~ (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled_fishonly2, nAGQ = 0)
AICc(col_mod_null)-min(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean$AICc)

ext_mod_null <- glmer(ext ~ (1|reg) + (1|spp), family = binomial, data = spp_master_ztemp_seus_buoy_scaled_fishonly2, nAGQ = 0)
AICc(ext_mod_null)-min(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean$AICc)

Relative Variable Importance for arrival Models

#add ∆AIC to tables
min_col_AICc_fishonly <- min(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[, AICc])
arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"deltaAICc" := (AICc - min_col_AICc_fishonly)]

#add relative likelihood exp( -0.5 * ∆AIC score for that model)
arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"rel_likelihood" := exp((-0.5 * deltaAICc))]
#sum relative likelihoods across all models
arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean.likelihoodsum <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[, rel_likelihood])
#Akaike weight for a model is this rel_likelihood devided by the sum of these values across all models
arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"akaike_weight" := rel_likelihood/arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean.likelihoodsum]

#I want to look at relative importance FOR 
#bottom/surface (bottom = includes sbt, grepl("sbt", variable))
col_bottom_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("sbt", variable), ]$akaike_weight)
col_surface_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("sst", variable), ]$akaike_weight)

#lag/not lagged (grepl("lag", variable))
col_lag_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag", variable), ]$akaike_weight)
col_nolag_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[!grep("lag", variable), ]$akaike_weight)

#absolute (grepl("abs", variable))
col_abs_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("abs", variable), ]$akaike_weight)

#raw (!grepl("change"))
col_raw_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[!grep("change", variable), ]$akaike_weight)

#change (grepl("change", variable), (!grepl("abs")))
col_change_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("change", variable), ][!grep("abs", variable),]$akaike_weight)

#type of temp variable (max, min, seas)
col_max_temp_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("max", variable), ]$akaike_weight)
col_min_temp_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("min", variable), ]$akaike_weight)
col_seas_temp_importance_fishonly <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("seas", variable), ]$akaike_weight)

Relative Variable Importance for departure Models

#add ∆AIC to tables
min_ext_AICc_fishonly <- min(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[, AICc])
departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"deltaAICc" := (AICc - min_ext_AICc_fishonly)]

#add relative likelihood exp( -0.5 * ∆AIC score for that model)
departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"rel_likelihood" := exp((-0.5 * deltaAICc))]
#sum relative likelihoods across all models
departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean.likelihoodsum <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[, rel_likelihood])
#Akaike weight for a model is this rel_likelihood devided by the sum of these values across all models
departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[,"akaike_weight" := rel_likelihood/departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean.likelihoodsum]

#I want to look at relative importance FOR 
#bottom/surface (bottom = includes sbt, grepl("sbt", variable))
ext_bottom_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("sbt", variable), ]$akaike_weight)
ext_surface_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("sst", variable), ]$akaike_weight)

#lag/not lagged (grepl("lag", variable))
ext_lag_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag", variable), ]$akaike_weight)
ext_nolag_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[!grep("lag", variable), ]$akaike_weight)

#absolute (grepl("abs", variable))
ext_abs_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("abs", variable), ]$akaike_weight)

#raw (!grepl("change"))
ext_raw_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[!grep("change", variable), ]$akaike_weight)

#change (grepl("change", variable), (!grepl("abs")))
ext_change_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("change", variable), ][!grep("abs", variable),]$akaike_weight)

#type of temp variable (max, min, seas)
ext_max_temp_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("max", variable), ]$akaike_weight)
ext_min_temp_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("min", variable), ]$akaike_weight)
ext_seas_temp_importance_fishonly <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("seas", variable), ]$akaike_weight)

Let’s see how the RVI importance varies by looking at specific lag values

#first, table for lags
lags_v_RVI_spprandom_scaled_fishonly <- data.table(col_lag = c(0:9), col_RVI = 0, departure_RVI = 0)
#arrival
lags_v_RVI_spprandom_scaled_fishonly[1,2] <- 1-sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[2,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag1", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[3,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag2", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[4,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag3", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[5,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag4", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[6,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag5", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[7,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag6", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[8,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag7", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[9,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag8", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[10,2] <- sum(arrival_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag9", variable), ]$akaike_weight)
#departure
lags_v_RVI_spprandom_scaled_fishonly[1,3] <- 1-sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[2,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag1", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[3,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag2", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[4,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag3", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[5,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag4", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[6,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag5", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[7,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag6", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[8,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag7", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[9,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag8", variable), ]$akaike_weight)
lags_v_RVI_spprandom_scaled_fishonly[10,3] <- sum(departure_model_comparison_spprandom_scaled_seus_update_fishonly_nomean[grep("lag9", variable), ]$akaike_weight)

ggplot(data = lags_v_RVI_spprandom_scaled_fishonly, aes(x = col_lag)) +
  geom_line(aes(y = col_RVI), col = "blue") +
  geom_line(aes(y = departure_RVI), col = "red") +
  labs(x = "Lag", y = "Relative Variable Importance") +
  scale_color_discrete() + #how to make a legend
  theme_bw()

Table for RVI data for arrival

col_ext <- c("col","col","col","col","col", "col","col", "col", "col","col")
type <- c("depth", "depth", "lag", "lag", "Change?", "Change?", "Change?", "Temp", "Temp", "Temp")
variable <- c("bottom", "surface", "no_lag", "lagged", "absolute_value_change", "change", "raw", "Min", "Max", "Seas")
value <- c(col_bottom_importance_fishonly, col_surface_importance_fishonly, col_nolag_importance_fishonly, col_lag_importance_fishonly, col_abs_importance_fishonly, col_change_importance_fishonly, col_raw_importance_fishonly, col_min_temp_importance_fishonly, col_max_temp_importance_fishonly, col_seas_temp_importance_fishonly)

RVI_col_fishonly <- data.table(col_ext, type, variable, value)

Table for RVI data for departure

col_ext <- c("ext","ext","ext","ext","ext", "ext", "ext", "ext", "ext", "ext")
type <- c("depth", "depth", "lag", "lag", "Change?", "Change?", "Change?", "Temp", "Temp", "Temp")
variable <- c("bottom", "surface", "no_lag", "lagged", "absolute_value_change", "change", "raw", "Min", "Max", "Seas")
value <- c(ext_bottom_importance_fishonly, ext_surface_importance_fishonly, ext_nolag_importance_fishonly, ext_lag_importance_fishonly, ext_abs_importance_fishonly, ext_change_importance_fishonly, ext_raw_importance_fishonly, ext_min_temp_importance_fishonly, ext_max_temp_importance_fishonly, ext_seas_temp_importance_fishonly)

RVI_ext_fishonly <- data.table(col_ext, type, variable, value)

Merge RVI tables for arrival and departure, and then graph

RVI_table_fishonly <- as.data.table(rbind(RVI_col_fishonly, RVI_ext_fishonly)) #bind RVI for arrivals and departures

RVI_table.r_fishonly <- RVI_table_fishonly[!grep("surface", variable)][!grep("lagged", variable)]

#change order of factor levels
RVI_table.r_fishonly[, variable := factor(variable, levels = c("bottom", "no_lag", "raw", "change", "absolute_value_change", "Min", "Max", "Seas"))]

save(RVI_table_fishonly, file = "RVI_table_fishonly.Rdata")

ggplot(data = RVI_table.r_fishonly, aes(x=variable, y = value, fill = col_ext)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_x_discrete(breaks = c("bottom", "no_lag", "raw", "change", "absolute_value_change", "Min", "Max", "Seas"), labels = c("Bottom Temp", "No Lag", "Raw Temp", "Change in \nTemp", "| Change in\n Temp |", "Min Temp", "Max Temp", "Seas")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance")  +
  theme_bw()

Another way to visualize is stacked bar plot.

#put levels into correct order for viewing
RVI_table_fishonly[, variable := factor(variable, levels = c("bottom", "surface", "absolute_value_change", "change", "raw", "no_lag", "lagged", "Min", "Max", "Seas"))]
#make types factors as well
RVI_table_fishonly[,type := as.factor(type)]

#arrival
RVI_col_plot_fishonly <- ggplot(data = RVI_table_fishonly[col_ext == "col",], aes(x=type, y = value, fill = variable)) +
  geom_bar(stat="identity", color = "black") +
  scale_x_discrete(breaks = c("Change?", "depth", "lag", "Temp"), labels = c("Change in\ntemp?", "Metric\nDepth", "Lagged?", "Temp")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance") +
  theme_classic() +
  theme(text = element_text(size = 22)
        #, legend.position = "none"
        )

#departure
RVI_ext_plot_fishonly <- ggplot(data = RVI_table_fishonly[col_ext == "ext",], aes(x=type, y = value, fill = variable)) +
  geom_bar(stat="identity", color = "black") +
  scale_x_discrete(breaks = c("Change?", "depth", "lag", "Temp"), labels = c("Change in\ntemp?", "Metric\nDepth", "Lagged?", "Temp")) +
  labs(x = "Temperature Variables", y = "Relative Variable Importance") +
  theme_classic()  +
  theme(text = element_text(size = 22)
        #, legend.position = "none"
        )

RVI_table_fishonly
RVI_col_plot_fishonly
RVI_ext_plot_fishonly
LS0tCnRpdGxlOiAiQXJyaXZhbCBhbmQgRGVwYXJ0dXJlIEZpbmFsIE1vZGVscyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhIGNsZWFuZWQgdmVyc2lvbiBvZiAwNF8yNF8xOSBUZW1wIGxpbmsgdHJhaXQgZmlzaC5SbWQvMTFfMjBfMTlfVGVtcF9saW5rX3RyYWl0c19maXNoLlJtZC4KQ2hhbmdlcwoqIGltcHJvdmVkIGZvcm1hdHRpbmcKKiBlYXNpZXIgdG8gZm9sbG93Ciogc3BlY2llcyBhbmQgcmVnaW9uIGFzIHJhbmRvbSBlZmZlY3RzCiogc2NhbGluZyB0ZW1wZXJhdHVyZSB2YWx1ZXMKKiBzZXR0aW5nIG5BQ1EgdG8gMCwgc2VlIHdoeSBbaGVyZV0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvNzczMTMvd2h5LWNhbnQtaS1tYXRjaC1nbG1lci1mYW1pbHktYmlub21pYWwtb3V0cHV0LXdpdGgtbWFudWFsLWltcGxlbWVudGF0aW9uLW9mLWcpLiAKCmBgYHtyIHNldHVwfQpsaWJyYXJ5KE11TUluKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkod2VzYW5kZXJzb24pICMgdG8gY29sb3IgcGxvdHMKCnNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZCA8LSByZWFkUkRTKGhlcmUoIkRhdGEiLCJTcHBfbWFzdGVyIiwgInNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZC5yZHMiKSkKYGBgCgpSdW5uaW5nLCBhbmQgcmFua2luZyBhcnJpdmFsIG1vZGVscyB3aXRob3V0IHRyYWl0cwoKIyNIZXJlLCBJIHNjYWxlZCBhbGwgdGVtcGVyYXR1cmUgdmFsdWVzIGFjcm9zcyBhbGwgcmVnaW9ucywgYW5kIGluY2x1ZGVkIHNwZWNpZXMgYXMgYSByYW5kb20gZWZmZWN0LiBJbiBvcmRlciB0byBkbyB0aGlzLCBJIGhhZCB0byBjaGFuZ2UgdGhlIGFsZ29yaXRobSBzbGlnaHRseS0tbkFHUSA9IDAuCgpgYGB7ciBhcnJpdmFsIG1vZGVscyB3aXRob3V0IHRyYWl0c30KI25hbWVzIG9mIHNjYWxlZCBjb2x1bW5zCnZhcmlhYmxlc19zY2FsZWQgPC0gZ3JlcCgiKl9zY2FsZWQiLCBuYW1lcyhzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWQpLCB2YWx1ZSA9IFQpCgojZ29pbmcgdG8gbWFrZSBsb29wIHRvIG1ha2UgYWxsIG1vZGVscyBJIG5lZWQgdG8gbG9vayBhdCB3aXRoIGEgc2luZ2xlIHRlbXBlcmF0dXJlIHZhcmlhYmxlCgphcnJpdmFsX21vZGVsX2NvbXBhcmlzb24gPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aCh2YXJpYWJsZXNfc2NhbGVkKSkpCmFycml2YWxfbW9kZWxfY29tcGFyaXNvblssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25bLCBWMSA6PSBOVUxMXQoKZm9yIChpIGluIDE6bGVuZ3RoKHZhcmlhYmxlc19zY2FsZWQpKXsKICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KHZhcmlhYmxlc19zY2FsZWRbaV0pICsgKDF8cmVnKSArICgxfHNwcCksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcF9zZXVzX2J1b3lfc2NhbGVkLCBuQUdRID0gMCkKICBhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25baSx2YXJpYWJsZSA6PSB2YXJpYWJsZXNfc2NhbGVkW2ldXQogIGFycml2YWxfbW9kZWxfY29tcGFyaXNvbltpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICBhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25baSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgCiAgcHJpbnQocGFzdGUoaSwgbGVuZ3RoKHZhcmlhYmxlc19zY2FsZWQpLCBzZXAgPSAiLyIpKQogICAgCn0KCiNieSBzZXR0aW5nIG5BQ1EgdG8gMCwgYWxsIG1vZGVscyBjb252ZXJnZWQKCnNhdmVSRFMob2JqZWN0ID0gYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uLCBmaWxlID0gaGVyZSgiTW9kZWxfcmVzdWx0cyIsImFycml2YWxfbW9kZWxfcmVzdWx0cy5yZHMiKSkKYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uIDwtIHJlYWRSRFMoaGVyZSgiTW9kZWxfcmVzdWx0cyIsImFycml2YWxfbW9kZWxfcmVzdWx0cy5yZHMiKSkKCmBgYAoKRGVwYXJ0dXJlIE1vZGVscyB3aXRob3V0IFRyYWl0cwpgYGB7ciBkZXBhcnR1cmUgbW9kZWxzIHdpdGhvdXQgdHJhaXRzfQoKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb24gPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aCh2YXJpYWJsZXNfc2NhbGVkKSkpCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uWywgVjEgOj0gTlVMTF0KCmZvciAoaSBpbiAxOmxlbmd0aCh2YXJpYWJsZXNfc2NhbGVkKSl7CiAgbW9kIDwtIGdsbWVyKG5vd19leHQgfiBnZXQodmFyaWFibGVzX3NjYWxlZFtpXSkgKyAoMXxyZWcpICsgKDF8c3BwKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWQsIG5BR1EgPSAwKQogIGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uW2ksdmFyaWFibGUgOj0gdmFyaWFibGVzX3NjYWxlZFtpXV0KICBkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbltpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICBkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbltpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICBkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbltpLEFJQ2MgOj0gQUlDYyhtb2QpXQogIAogIHByaW50KHBhc3RlKGksIGxlbmd0aCh2YXJpYWJsZXNfc2NhbGVkKSwgc2VwID0gIi8iKSkKICAgIAp9CgojYnkgc2V0dGluZyBuQUNRIHRvIDAsIGFsbCBtb2RlbHMgY29udmVyZ2VkCgpzYXZlUkRTKG9iamVjdCA9IGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uLCBmaWxlID0gaGVyZSgiTW9kZWxfcmVzdWx0cyIsImRlcGFydHVyZV9tb2RlbF9yZXN1bHRzLnJkcyIpKQpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbiA8LSByZWFkUkRTKGhlcmUoIk1vZGVsX3Jlc3VsdHMiLCJkZXBhcnR1cmVfbW9kZWxfcmVzdWx0cy5yZHMiKSkKCmBgYAoKUmVsYXRpdmUgVmFyaWFibGUgSW1wb3J0YW5jZQoKTkI6IEkgZGlkbid0IGVuZCB1cCB1c2luZyBtZWFuIGFzIGEgcHJlZGljdG9yIHZhcmlhYmxlIChwYXR0ZXJucyBjYXB0dXJlZCBpbiBtaW4gYW5kIG1heCwgbGVzcyByZWxldmFudCB0byB0aGVybWFsIG5pY2hlKQpgYGB7ciBnZXQgcmlkIG9mIGFueSBtb2RlbHMgdXNpbmcgbWVhbn0KYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbiA8LSBhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25bIWdyZXBsKCJtZWFuIix2YXJpYWJsZSksXQoKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuIDwtIGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uWyFncmVwbCgibWVhbiIsdmFyaWFibGUpLF0KCgpgYGAKCkhvdyBkb2VzIHRoZSBudWxsIG1vZGVsIHdpdGggb25seSByYW5kb20gZWZmZWN0cyBwZXJmb3JtPwpgYGB7ciBudWxsIG1vZGVsc30KI2FkZCBudWxsIHRvIHRhYmxlcwppbnRlcmNlcHRfYXJyaXZhbF9tb2Rfc2NhbGVkIDwtIGdsbWVyKGNvbCB+ICgxfHNwcCkgKyAoMXxyZWcpLCBmYW1pbHkgPSBiaW5vbWlhbCwgbkFHUSA9IDAsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWQpCgppbnRlcmNlcHRfZGVwYXJ0dXJlX21vZF9zY2FsZWQgPC0gZ2xtZXIobm93X2V4dCB+ICgxfHJlZykgKyAoMXxzcHApLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZCwgbkFHUSA9IDApCgojYmVzdCBtb2RlbCBiZXR0ZXIgdGhhbiBudWxsPyB5ZXMKQUlDYyhpbnRlcmNlcHRfYXJyaXZhbF9tb2Rfc2NhbGVkKS1taW4oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uJEFJQ2MpCkFJQ2MoaW50ZXJjZXB0X2RlcGFydHVyZV9tb2Rfc2NhbGVkKS1taW4oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb24kQUlDYykKCgpgYGAKCgpSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIGZvciBBcnJpdmFsIE1vZGVscwpgYGB7ciBSVkkgYXJyaXZhbHN9CiNhZGQg4oiGQUlDIHRvIHRhYmxlcwptaW5fYXJyaXZhbF9BSUNjIDwtIG1pbihhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuWywgQUlDY10pCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bLCJkZWx0YUFJQ2MiIDo9IChBSUNjIC0gbWluX2Fycml2YWxfQUlDYyldCgojYWRkIHJlbGF0aXZlIGxpa2VsaWhvb2QgZXhwKCAtMC41ICog4oiGQUlDIHNjb3JlIGZvciB0aGF0IG1vZGVsKQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuWywicmVsX2xpa2VsaWhvb2QiIDo9IGV4cCgoLTAuNSAqIGRlbHRhQUlDYykpXQojc3VtIHJlbGF0aXZlIGxpa2VsaWhvb2RzIGFjcm9zcyBhbGwgbW9kZWxzCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW4ubGlrZWxpaG9vZHN1bSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhblssIHJlbF9saWtlbGlob29kXSkKI0FrYWlrZSB3ZWlnaHQgZm9yIGEgbW9kZWwgaXMgdGhpcyByZWxfbGlrZWxpaG9vZCBkaXZpZGVkIGJ5IHRoZSBzdW0gb2YgdGhlc2UgdmFsdWVzIGFjcm9zcyBhbGwgbW9kZWxzCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bLCJha2Fpa2Vfd2VpZ2h0IiA6PSByZWxfbGlrZWxpaG9vZC9hcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuLmxpa2VsaWhvb2RzdW1dCgojSSB3YW50IHRvIGxvb2sgYXQgcmVsYXRpdmUgaW1wb3J0YW5jZSBGT1I6CgojYm90dG9tL3N1cmZhY2UgKGJvdHRvbSA9IGluY2x1ZGVzIHNidCwgZ3JlcGwoInNidCIsIHZhcmlhYmxlKSkKYXJyaXZhbF9ib3R0b21faW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzYnQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKYXJyaXZhbF9zdXJmYWNlX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic3N0IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojbGFnL25vdCBsYWdnZWQgKGdyZXBsKCJsYWciLCB2YXJpYWJsZSkpCmFycml2YWxfbGFnX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmFycml2YWxfbm9sYWdfaW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhblshZ3JlcCgibGFnIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojYWJzb2x1dGUgKGdyZXBsKCJhYnMiLCB2YXJpYWJsZSkpCmFycml2YWxfYWJzX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgiYWJzIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojcmF3ICghZ3JlcGwoImNoYW5nZSIpKQphcnJpdmFsX3Jhd19pbXBvcnRhbmNlIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuWyFncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNjaGFuZ2UgKGdyZXBsKCJjaGFuZ2UiLCB2YXJpYWJsZSksICghZ3JlcGwoImFicyIpKSkKYXJyaXZhbF9jaGFuZ2VfaW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKSxdJGFrYWlrZV93ZWlnaHQpCgojdHlwZSBvZiB0ZW1wIHZhcmlhYmxlIChtYXgsIG1pbiwgc2VhcykKYXJyaXZhbF9tYXhfdGVtcF9pbXBvcnRhbmNlIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1heCIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQphcnJpdmFsX21pbl90ZW1wX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWluIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmFycml2YWxfc2Vhc190ZW1wX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic2VhcyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzIDwtIGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW4KCnNhdmVSRFMoYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzLCBmaWxlID0gaGVyZSgiTW9kZWxfcmVzdWx0cyIsImFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5fYWthaWtld2VpZ2h0cy5yZHMiKSkKc2F2ZVJEUyhhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuX2FrYWlrZXdlaWdodHMsIGZpbGUgPSBoZXJlKCJ0YWJsZXMiLCJhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuX2FrYWlrZXdlaWdodHMucmRzIikpCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5fYWthaWtld2VpZ2h0cyA8LSByZWFkUkRTKGZpbGUgPSBoZXJlKCJNb2RlbF9yZXN1bHRzIiwiYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzLnJkcyIpKQoKYGBgCgpSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIGZvciBkaWZmZXJlbnQgUGFpcnMgb2YgVHJhbnNmb3JtYXRpb24gYW5kIE1ldHJpYwpgYGB7ciBSVkkgYXJyaXZhbCBQYWlycyBUcmFuc2Zvcm1hdGlvbiBhbmQgTWV0cmljfQoKI0kgd2FudCB0byBsb29rIGF0IHJlbGF0aXZlIGltcG9ydGFuY2UgRk9SIAojbW9kZWxzIHdpdGggcmF3IGFuZCBtaW4KYXJyaXZhbF9yYXdfbWluX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWluIiwgdmFyaWFibGUpLCBdWyFncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggcmF3IGFuZCBtYXgKYXJyaXZhbF9yYXdfbWF4X2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWF4IiwgdmFyaWFibGUpLCBdWyFncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggcmF3IGFuZCBzZWFzCmFycml2YWxfcmF3X3NlYXNfaW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzZWFzIiwgdmFyaWFibGUpLCBdWyFncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgoKI21vZGVscyB3aXRoIGNoYW5nZSBhbmQgbWluCmFycml2YWxfY2hhbmdlX21pbl9pbXBvcnRhbmNlIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1pbl9zLnRfdGVtcF9jaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKV0kYWthaWtlX3dlaWdodCkKCiNtb2RlbHMgd2l0aCBjaGFuZ2UgYW5kIG1heAphcnJpdmFsX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtYXhfcy50X3RlbXBfY2hhbmdlIiwgdmFyaWFibGUpLCBdWyFncmVwKCJhYnMiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggY2hhbmdlIGFuZCBzZWFzCmFycml2YWxfY2hhbmdlX3NlYXNfaW1wb3J0YW5jZSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzZWFzX3MudF90ZW1wX2NoYW5nZSIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiYWJzIiwgdmFyaWFibGUpXSRha2Fpa2Vfd2VpZ2h0KQoKI21vZGVscyB3aXRoIGFicyBjaGFuZ2UgYW5kIG1pbgphcnJpdmFsX2Fic19jaGFuZ2VfbWluX2ltcG9ydGFuY2UgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWluX3MudF90ZW1wX2NoYW5nZV9hYnMiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNtb2RlbHMgd2l0aCBhYnMgY2hhbmdlIGFuZCBtYXgKYXJyaXZhbF9hYnNfY2hhbmdlX21heF9pbXBvcnRhbmNlIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1heF9zLnRfdGVtcF9jaGFuZ2VfYWJzIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggYWJzIGNoYW5nZSBhbmQgc2VhcwphcnJpdmFsX2Fic19jaGFuZ2Vfc2Vhc19pbXBvcnRhbmNlIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoInNlYXNfcy50X3RlbXBfY2hhbmdlX2FicyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKYXJyaXZhbF90cmFuc2Zvcm1fbWV0cmljX2NvbXBhcmlzb24gPC0gZGF0YS50YWJsZShUcmFuc2Zvcm1hdGlvbiA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInJhdyIsICJyYXciLCAicmF3IiwgImNoYW5nZSIsICJjaGFuZ2UiLCAiY2hhbmdlIiwgImFic19jaGFuZ2UiLCAiYWJzX2NoYW5nZSIsICJhYnNfY2hhbmdlIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0cmljID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcChjKCJtaW4iLCAibWF4IiwgInNlYXMiKSwgMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlZJID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoYXJyaXZhbF9yYXdfbWluX2ltcG9ydGFuY2UsIGFycml2YWxfcmF3X21heF9pbXBvcnRhbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJpdmFsX3Jhd19zZWFzX2ltcG9ydGFuY2UsIGFycml2YWxfY2hhbmdlX21pbl9pbXBvcnRhbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJpdmFsX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgYXJyaXZhbF9jaGFuZ2Vfc2Vhc19pbXBvcnRhbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJpdmFsX2Fic19jaGFuZ2VfbWluX2ltcG9ydGFuY2UsIGFycml2YWxfYWJzX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyaXZhbF9hYnNfY2hhbmdlX3NlYXNfaW1wb3J0YW5jZSkpCgoKYGBgCgoKUmVsYXRpdmUgVmFyaWFibGUgSW1wb3J0YW5jZSBEZXBhcnR1cmUgTW9kZWxzCmBgYHtyIFJWSSBkZXBhcnR1cmV9CiNhZGQg4oiGQUlDIHRvIHRhYmxlcwptaW5fZGVwYXJ0dXJlX0FJQ2MgPC0gbWluKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhblssIEFJQ2NdKQpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bLCJkZWx0YUFJQ2MiIDo9IChBSUNjIC0gbWluX2RlcGFydHVyZV9BSUNjKV0KCiNhZGQgcmVsYXRpdmUgbGlrZWxpaG9vZCBleHAoIC0wLjUgKiDiiIZBSUMgc2NvcmUgZm9yIHRoYXQgbW9kZWwpCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhblssInJlbF9saWtlbGlob29kIiA6PSBleHAoKC0wLjUgKiBkZWx0YUFJQ2MpKV0KI3N1bSByZWxhdGl2ZSBsaWtlbGlob29kcyBhY3Jvc3MgYWxsIG1vZGVscwpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW4ubGlrZWxpaG9vZHN1bSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuWywgcmVsX2xpa2VsaWhvb2RdKQojQWthaWtlIHdlaWdodCBmb3IgYSBtb2RlbCBpcyB0aGlzIHJlbF9saWtlbGlob29kIGRldmlkZWQgYnkgdGhlIHN1bSBvZiB0aGVzZSB2YWx1ZXMgYWNyb3NzIGFsbCBtb2RlbHMKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuWywiYWthaWtlX3dlaWdodCIgOj0gcmVsX2xpa2VsaWhvb2QvZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuLmxpa2VsaWhvb2RzdW1dCgojSSB3YW50IHRvIGxvb2sgYXQgcmVsYXRpdmUgaW1wb3J0YW5jZSBGT1IgCiNib3R0b20vc3VyZmFjZSAoYm90dG9tID0gaW5jbHVkZXMgc2J0LCBncmVwbCgic2J0IiwgdmFyaWFibGUpKQpkZXBhcnR1cmVfYm90dG9tX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzYnQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZGVwYXJ0dXJlX3N1cmZhY2VfaW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoInNzdCIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2xhZy9ub3QgbGFnZ2VkIChncmVwbCgibGFnIiwgdmFyaWFibGUpKQpkZXBhcnR1cmVfbGFnX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZGVwYXJ0dXJlX25vbGFnX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhblshZ3JlcCgibGFnIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojYWJzb2x1dGUgKGdyZXBsKCJhYnMiLCB2YXJpYWJsZSkpCmRlcGFydHVyZV9hYnNfaW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImFicyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI3JhdyAoIWdyZXBsKCJjaGFuZ2UiKSkKZGVwYXJ0dXJlX3Jhd19pbXBvcnRhbmNlIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bIWdyZXAoImNoYW5nZSIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2NoYW5nZSAoZ3JlcGwoImNoYW5nZSIsIHZhcmlhYmxlKSwgKCFncmVwbCgiYWJzIikpKQpkZXBhcnR1cmVfY2hhbmdlX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKSxdJGFrYWlrZV93ZWlnaHQpCgojdHlwZSBvZiB0ZW1wIHZhcmlhYmxlIChtYXgsIG1pbiwgc2VhcykKZGVwYXJ0dXJlX21heF90ZW1wX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtYXgiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZGVwYXJ0dXJlX21pbl90ZW1wX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtaW4iLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZGVwYXJ0dXJlX3NlYXNfdGVtcF9pbXBvcnRhbmNlIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic2VhcyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuX2FrYWlrZXdlaWdodHMgPC0gZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuCgpzYXZlUkRTKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzLCBmaWxlID0gaGVyZSgiTW9kZWxfcmVzdWx0cyIsImRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzLnJkcyIpKQpzYXZlUkRTKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzLCBmaWxlID0gaGVyZSgidGFibGVzIiwiZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuX2FrYWlrZXdlaWdodHMucmRzIikpCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbl9ha2Fpa2V3ZWlnaHRzIDwtIHJlYWRSRFMoZmlsZSA9IGhlcmUoIk1vZGVsX3Jlc3VsdHMiLCJkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5fYWthaWtld2VpZ2h0cy5yZHMiKSkKCmBgYAoKUmVsYXRpdmUgVmFyaWFibGUgSW1wb3J0YW5jZSBmb3IgUGFpcnMgb2YgVHJhbnNmb3JtYXRpb24gYW5kIE1ldHJpYyBQcmVkaWN0aW5nIGRlcGFydHVyZXMKYGBge3IgUlZJIGRlcGFydHVyZSBQYWlycyBUcmFuc2Zvcm1hdGlvbiBhbmQgTWV0cmljfQoKI0kgd2FudCB0byBsb29rIGF0IHJlbGF0aXZlIGltcG9ydGFuY2UgRk9SIAojbW9kZWxzIHdpdGggcmF3IGFuZCBtaW4KZGVwYXJ0dXJlX3Jhd19taW5faW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1pbiIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiY2hhbmdlIiwgdmFyaWFibGUpXSRha2Fpa2Vfd2VpZ2h0KQoKI21vZGVscyB3aXRoIHJhdyBhbmQgbWF4CmRlcGFydHVyZV9yYXdfbWF4X2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtYXgiLCB2YXJpYWJsZSksIF1bIWdyZXAoImNoYW5nZSIsIHZhcmlhYmxlKV0kYWthaWtlX3dlaWdodCkKCiNtb2RlbHMgd2l0aCByYXcgYW5kIHNlYXMKZGVwYXJ0dXJlX3Jhd19zZWFzX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzZWFzIiwgdmFyaWFibGUpLCBdWyFncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgoKI21vZGVscyB3aXRoIGNoYW5nZSBhbmQgbWluCmRlcGFydHVyZV9jaGFuZ2VfbWluX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtaW5fcy50X3RlbXBfY2hhbmdlIiwgdmFyaWFibGUpLCBdWyFncmVwKCJhYnMiLCB2YXJpYWJsZSldJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggY2hhbmdlIGFuZCBtYXgKZGVwYXJ0dXJlX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1heF9zLnRfdGVtcF9jaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKV0kYWthaWtlX3dlaWdodCkKCiNtb2RlbHMgd2l0aCBjaGFuZ2UgYW5kIHNlYXMKZGVwYXJ0dXJlX2NoYW5nZV9zZWFzX2ltcG9ydGFuY2UgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJzZWFzX3MudF90ZW1wX2NoYW5nZSIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiYWJzIiwgdmFyaWFibGUpXSRha2Fpa2Vfd2VpZ2h0KQoKI21vZGVscyB3aXRoIGFicyBjaGFuZ2UgYW5kIG1pbgpkZXBhcnR1cmVfYWJzX2NoYW5nZV9taW5faW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoIm1pbl9zLnRfdGVtcF9jaGFuZ2VfYWJzIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojbW9kZWxzIHdpdGggYWJzIGNoYW5nZSBhbmQgbWF4CmRlcGFydHVyZV9hYnNfY2hhbmdlX21heF9pbXBvcnRhbmNlIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWF4X3MudF90ZW1wX2NoYW5nZV9hYnMiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNtb2RlbHMgd2l0aCBhYnMgY2hhbmdlIGFuZCBzZWFzCmRlcGFydHVyZV9hYnNfY2hhbmdlX3NlYXNfaW1wb3J0YW5jZSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoInNlYXNfcy50X3RlbXBfY2hhbmdlX2FicyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKZGVwYXJ0dXJlX3RyYW5zZm9ybV9tZXRyaWNfY29tcGFyaXNvbiA8LSBkYXRhLnRhYmxlKFRyYW5zZm9ybWF0aW9uID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygicmF3IiwgInJhdyIsICJyYXciLCAiY2hhbmdlIiwgImNoYW5nZSIsICJjaGFuZ2UiLCAiYWJzX2NoYW5nZSIsICJhYnNfY2hhbmdlIiwgImFic19jaGFuZ2UiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRyaWMgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKGMoIm1pbiIsICJtYXgiLCAic2VhcyIpLCAzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSVkkgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhkZXBhcnR1cmVfcmF3X21pbl9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfcmF3X21heF9pbXBvcnRhbmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBhcnR1cmVfcmF3X3NlYXNfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9taW5faW1wb3J0YW5jZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwYXJ0dXJlX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9zZWFzX2ltcG9ydGFuY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGFydHVyZV9hYnNfY2hhbmdlX21pbl9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfYWJzX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwYXJ0dXJlX2Fic19jaGFuZ2Vfc2Vhc19pbXBvcnRhbmNlKSkKCmBgYAoKCkxldCdzIHNlZSBob3cgdGhlIFJWSSBpbXBvcnRhbmNlIHZhcmllcyBieSBsb29raW5nIGF0IHNwZWNpZmljIGxhZyB2YWx1ZXMKYGBge3IgbWFrZSBhIHBsb3QgaGVyZSBmb3IgdmFyaWFiaWxpdHkgYWNyb3NzIGxhZyB2YWx1ZXN9CgojZmlyc3QsIHRhYmxlIGZvciBsYWdzCmxhZ3NfUlZJX3NjYWxlZCA8LSBkYXRhLnRhYmxlKGFycml2YWxfbGFnID0gYygwOjkpLCBhcnJpdmFsX1JWSSA9IDAsIGRlcGFydHVyZV9SVkkgPSAwKQoKI2Fycml2YWxzCmxhZ3NfUlZJX3NjYWxlZFsxLDJdIDwtIDEtc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFsyLDJdIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzEiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzMsMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnMiIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbNCwyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWczIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFs1LDJdIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzYsMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnNSIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbNywyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWc2IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFs4LDJdIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzksMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnOCIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbMTAsMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnOSIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2RlcGFydHVyZXMKbGFnc19SVklfc2NhbGVkWzEsM10gPC0gMS1zdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbMiwzXSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzEiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzMsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWcyIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFs0LDNdIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnMyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbNSwzXSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzYsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWc1IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFs3LDNdIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibGFnNiIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX1JWSV9zY2FsZWRbOCwzXSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc19SVklfc2NhbGVkWzksM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJsYWc4IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3NfUlZJX3NjYWxlZFsxMCwzXSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoImxhZzkiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCnNhdmVSRFMobGFnc19SVklfc2NhbGVkLCBoZXJlKCJNb2RlbF9yZXN1bHRzIiwibGFnc19SVklfc2NhbGVkLnJkcyIpKQoKI3Zpc3VhbGl6ZSBsYWdzIHRocm91Z2ggdGltZQpnZ3Bsb3QoZGF0YSA9IGxhZ3NfUlZJX3NjYWxlZCwgYWVzKHggPSBhcnJpdmFsX2xhZykpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBhcnJpdmFsX1JWSSksICkgKwogIGdlb21fbGluZShhZXMoeSA9IGRlcGFydHVyZV9SVkkpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgbGFicyh4ID0gIkxhZyAoeWVhcnMpIiwgeSA9ICJSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIikgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKCkgKyAjaG93IHRvIG1ha2UgYSBsZWdlbmQKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDA6OSkpCgpgYGAKClRhYmxlIGZvciBSVkkgZGF0YSBmb3IgYXJyaXZhbApgYGB7ciBwdXQgUlZJcyBmb3IgYXJyaXZhbCBpbnRvIGRhdGEgdGFibGV9CmFycml2YWxfZGVwYXJ0dXJlIDwtIGMoImFycml2YWwiLCJhcnJpdmFsIiwiYXJyaXZhbCIsImFycml2YWwiLCJhcnJpdmFsIiwgImFycml2YWwiLCJhcnJpdmFsIiwgImFycml2YWwiLCAiYXJyaXZhbCIsImFycml2YWwiLCJhcnJpdmFsIiwiYXJyaXZhbCIsImFycml2YWwiLCJhcnJpdmFsIiwgImFycml2YWwiLCJhcnJpdmFsIiwgImFycml2YWwiLCAiYXJyaXZhbCIsImFycml2YWwiKQp0eXBlIDwtIGMoIkRlcHRoIiwgIkRlcHRoIiwgImxhZyIsICJsYWciLCAiVHJhbnNmb3JtYXRpb24iLCAiVHJhbnNmb3JtYXRpb24iLCAiVHJhbnNmb3JtYXRpb24iLCAiTWV0cmljIiwgIk1ldHJpYyIsICJNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiKQp2YXJpYWJsZSA8LSBjKCJCb3R0b20iLCAiU3VyZmFjZSIsICJub19sYWciLCAibGFnZ2VkIiwgInxDaGFuZ2V8IiwgIkNoYW5nZSIsICJSYXciLCAiTWluIiwgIk1heCIsICJTZWFzIiwgIlJhdyB4IE1pbiIsICJSYXcgeCBNYXgiLCAiUmF3IHggU2VhcyIsICJDaGFuZ2UgeCBNaW4iLCAiQ2hhbmdlIHggTWF4IiwgIkNoYW5nZSB4IFNlYXMiLCAifENoYW5nZXwgeCBNaW4iLCAifENoYW5nZXwgeCBNYXgiLCAifENoYW5nZXwgeCBTZWFzIikKCgp2YWx1ZSA8LSBjKGFycml2YWxfYm90dG9tX2ltcG9ydGFuY2UsIGFycml2YWxfc3VyZmFjZV9pbXBvcnRhbmNlLCBhcnJpdmFsX25vbGFnX2ltcG9ydGFuY2UsIGFycml2YWxfbGFnX2ltcG9ydGFuY2UsIGFycml2YWxfYWJzX2ltcG9ydGFuY2UsIGFycml2YWxfY2hhbmdlX2ltcG9ydGFuY2UsIGFycml2YWxfcmF3X2ltcG9ydGFuY2UsIGFycml2YWxfbWluX3RlbXBfaW1wb3J0YW5jZSwgYXJyaXZhbF9tYXhfdGVtcF9pbXBvcnRhbmNlLCBhcnJpdmFsX3NlYXNfdGVtcF9pbXBvcnRhbmNlLCBhcnJpdmFsX3Jhd19taW5faW1wb3J0YW5jZSwgYXJyaXZhbF9yYXdfbWF4X2ltcG9ydGFuY2UsIGFycml2YWxfcmF3X3NlYXNfaW1wb3J0YW5jZSwgYXJyaXZhbF9jaGFuZ2VfbWluX2ltcG9ydGFuY2UsIGFycml2YWxfY2hhbmdlX21heF9pbXBvcnRhbmNlLCBhcnJpdmFsX2NoYW5nZV9zZWFzX2ltcG9ydGFuY2UsIGFycml2YWxfYWJzX2NoYW5nZV9taW5faW1wb3J0YW5jZSwgYXJyaXZhbF9hYnNfY2hhbmdlX21heF9pbXBvcnRhbmNlLCBhcnJpdmFsX2Fic19jaGFuZ2Vfc2Vhc19pbXBvcnRhbmNlKQoKUlZJX2Fycml2YWwgPC0gZGF0YS50YWJsZShhcnJpdmFsX2RlcGFydHVyZSwgdHlwZSwgdmFyaWFibGUsIHZhbHVlKQpgYGAKClRhYmxlIGZvciBSVkkgZGF0YSBmb3IgZGVwYXJ0dXJlCmBgYHtyIHB1dCBSVklzIGZvciBkZXBhcnR1cmUgaW50byBkYXRhIHRhYmxlfQphcnJpdmFsX2RlcGFydHVyZSA8LSBjKCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCAiZGVwYXJ0dXJlIiwiZGVwYXJ0dXJlIiwgImRlcGFydHVyZSIsICJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiLCAiZGVwYXJ0dXJlIiwiZGVwYXJ0dXJlIiwgImRlcGFydHVyZSIsICJkZXBhcnR1cmUiLCJkZXBhcnR1cmUiKQp0eXBlIDwtIGMoIkRlcHRoIiwgIkRlcHRoIiwgImxhZyIsICJsYWciLCAiVHJhbnNmb3JtYXRpb24iLCAiVHJhbnNmb3JtYXRpb24iLCAiVHJhbnNmb3JtYXRpb24iLCAiTWV0cmljIiwgIk1ldHJpYyIsICJNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiLCAiVHJhbnNmb3JtYXRpb24geCBNZXRyaWMiKQp2YXJpYWJsZSA8LSBjKCJCb3R0b20iLCAiU3VyZmFjZSIsICJub19sYWciLCAibGFnZ2VkIiwgInxDaGFuZ2V8IiwgIkNoYW5nZSIsICJSYXciLCAiTWluIiwgIk1heCIsICJTZWFzIiwgIlJhdyB4IE1pbiIsICJSYXcgeCBNYXgiLCAiUmF3IHggU2VhcyIsICJDaGFuZ2UgeCBNaW4iLCAiQ2hhbmdlIHggTWF4IiwgIkNoYW5nZSB4IFNlYXMiLCAifENoYW5nZXwgeCBNaW4iLCAifENoYW5nZXwgeCBNYXgiLCAifENoYW5nZXwgeCBTZWFzIikKdmFsdWUgPC0gYyhkZXBhcnR1cmVfYm90dG9tX2ltcG9ydGFuY2UsIGRlcGFydHVyZV9zdXJmYWNlX2ltcG9ydGFuY2UsIGRlcGFydHVyZV9ub2xhZ19pbXBvcnRhbmNlLCBkZXBhcnR1cmVfbGFnX2ltcG9ydGFuY2UsIGRlcGFydHVyZV9hYnNfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfcmF3X2ltcG9ydGFuY2UsIGRlcGFydHVyZV9taW5fdGVtcF9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfbWF4X3RlbXBfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX3NlYXNfdGVtcF9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfcmF3X21pbl9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfcmF3X21heF9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfcmF3X3NlYXNfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9taW5faW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2NoYW5nZV9zZWFzX2ltcG9ydGFuY2UsIGRlcGFydHVyZV9hYnNfY2hhbmdlX21pbl9pbXBvcnRhbmNlLCBkZXBhcnR1cmVfYWJzX2NoYW5nZV9tYXhfaW1wb3J0YW5jZSwgZGVwYXJ0dXJlX2Fic19jaGFuZ2Vfc2Vhc19pbXBvcnRhbmNlKQoKUlZJX2RlcGFydHVyZSA8LSBkYXRhLnRhYmxlKGFycml2YWxfZGVwYXJ0dXJlLCB0eXBlLCB2YXJpYWJsZSwgdmFsdWUpCmBgYAoKTWVyZ2UgUlZJIHRhYmxlcyBmb3IgYXJyaXZhbCBhbmQgZGVwYXJ0dXJlLCBhbmQgdGhlbiBncmFwaApgYGB7ciBtZXJnZSBSVkkgdGFibGVzIGFuZCBwbG90fQpSVklfdGFibGUgPC0gYXMuZGF0YS50YWJsZShyYmluZChSVklfYXJyaXZhbCwgUlZJX2RlcGFydHVyZSkpICNiaW5kIFJWSSBmb3IgYXJyaXZhbHMgYW5kIGRlcGFydHVyZXMKClJWSV90YWJsZS5yIDwtIFJWSV90YWJsZVshZ3JlcCgiU3VyZmFjZSIsIHZhcmlhYmxlKV1bIWdyZXAoImxhZ2dlZCIsIHZhcmlhYmxlKV0KCiNjaGFuZ2Ugb3JkZXIgb2YgZmFjdG9yIGxldmVscwpSVklfdGFibGUuclssIHZhcmlhYmxlIDo9IGZhY3Rvcih2YXJpYWJsZSwgbGV2ZWxzID0gYygiQm90dG9tIiwgIm5vX2xhZyIsICJSYXciLCAiQ2hhbmdlIiwgInxDaGFuZ2V8IiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpKV0KCnNhdmVSRFMoUlZJX3RhYmxlLCBmaWxlID0gaGVyZSgiTW9kZWxfcmVzdWx0cyIsICJSVklfdGFibGUucmRzIikpCgpnZ3Bsb3QoZGF0YSA9IFJWSV90YWJsZS5yLCBhZXMoeD12YXJpYWJsZSwgeSA9IHZhbHVlLCBmaWxsID0gYXJyaXZhbF9kZXBhcnR1cmUpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gYygiQm90dG9tIiwgIm5vX2xhZyIsICJSYXciLCAiQ2hhbmdlIiwgInxDaGFuZ2V8IiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpLCAKICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkJvdHRvbSBUZW1wIiwgIk5vIExhZyIsICJSYXcgVGVtcCIsICJDaGFuZ2UgaW4gXG5UZW1wIiwgInwgQ2hhbmdlIGluXG4gVGVtcCB8IiwgIk1pbiBUZW1wIiwgIk1heCBUZW1wIiwgIlNlYXMiKSkgKwogIGxhYnMoeCA9ICJUZW1wZXJhdHVyZSBWYXJpYWJsZXMiLCB5ID0gIlJlbGF0aXZlIFZhcmlhYmxlIEltcG9ydGFuY2UiKSAgKwogIHRoZW1lX2J3KCkKCmBgYAoKQW5vdGhlciB3YXkgdG8gdmlzdWFsaXplIGlzIHN0YWNrZWQgYmFyIHBsb3QuCgpgYGB7ciBSVkkgc3RhY2tlZCBwbG90fQojcHV0IGxldmVscyBpbnRvIGNvcnJlY3Qgb3JkZXIgZm9yIHZpZXdpbmcsIGFuZCBhZGQgZHVtbXkgbGV2ZWwgZm9yIGxlZ2VuZApSVklfYXJyaXZhbFssIHZhcmlhYmxlIDo9IGZhY3Rvcih2YXJpYWJsZSwgbGV2ZWxzID0gYygiQm90dG9tIiwgIlN1cmZhY2UiLCIgICIsICJSYXciLCAiQ2hhbmdlIiwgInxDaGFuZ2V8IiwgIm5vX2xhZyIsICJsYWdnZWQiLCAiTWluIiwgIk1heCIsICJTZWFzIikpXQpSVklfYXJyaXZhbFssIHR5cGUgOj0gZmFjdG9yKHR5cGUsIGxldmVscyA9IGMoIkRlcHRoIiwgIlRyYW5zZm9ybWF0aW9uIiwgIk1ldHJpYyIsICJsYWciKSldCgpSVklfYXJyaXZhbF9ub2xhZyA8LSBSVklfYXJyaXZhbFt0eXBlICE9ICJsYWciLF0KUlZJX2Fycml2YWxfbm9sYWdbLCB0eXBlIDo9IGZhY3Rvcih0eXBlLCBsZXZlbHMgPSBjKCJEZXB0aCIsICJUcmFuc2Zvcm1hdGlvbiIsICJNZXRyaWMiKSldWywgdmFyaWFibGUgOj0gZmFjdG9yKHZhcmlhYmxlLCBsZXZlbHMgPSBjKCJCb3R0b20iLCAiU3VyZmFjZSIsIiAgIiwgIlJhdyIsICJDaGFuZ2UiLCAifENoYW5nZXwiLCAiTWluIiwgIk1heCIsICJTZWFzIikpXQoKc2F2ZVJEUyhSVklfYXJyaXZhbF9ub2xhZywgaGVyZSgiTW9kZWxfcmVzdWx0cyIsICJSVklfYXJyaXZhbF9ub2xhZy5yZHMiKSkKCiNhbmQgYWdhaW4gZm9yIGRlcGFydHVyZQpSVklfZGVwYXJ0dXJlWywgdmFyaWFibGUgOj0gZmFjdG9yKHZhcmlhYmxlLCBsZXZlbHMgPSBjKCJCb3R0b20iLCAiU3VyZmFjZSIsIiAgIiwgIlJhdyIsICJDaGFuZ2UiLCAifENoYW5nZXwiLCAibm9fbGFnIiwgImxhZ2dlZCIsICJNaW4iLCAiTWF4IiwgIlNlYXMiKSldClJWSV9kZXBhcnR1cmVbLCB0eXBlIDo9IGZhY3Rvcih0eXBlLCBsZXZlbHMgPSBjKCJEZXB0aCIsICJUcmFuc2Zvcm1hdGlvbiIsICJNZXRyaWMiLCAibGFnIikpXQoKUlZJX2RlcGFydHVyZV9ub2xhZyA8LSBSVklfZGVwYXJ0dXJlW3R5cGUgIT0gImxhZyIsXQpSVklfZGVwYXJ0dXJlX25vbGFnWywgdHlwZSA6PSBmYWN0b3IodHlwZSwgbGV2ZWxzID0gYygiRGVwdGgiLCAiVHJhbnNmb3JtYXRpb24iLCAiTWV0cmljIikpXVssIHZhcmlhYmxlIDo9IGZhY3Rvcih2YXJpYWJsZSwgbGV2ZWxzID0gYygiQm90dG9tIiwgIlN1cmZhY2UiLCIgICIsICJSYXciLCAiQ2hhbmdlIiwgInxDaGFuZ2V8IiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpKV0KCnNhdmVSRFMoUlZJX2RlcGFydHVyZV9ub2xhZywgaGVyZSgiTW9kZWxfcmVzdWx0cyIsICJSVklfZGVwYXJ0dXJlX25vbGFnLnJkcyIpKQoKCiNwbG90dGluZwpwYWwgPC0gd2VzX3BhbGV0dGUoIkdyYW5kQnVkYXBlc3QxIiwgOCwgdHlwZSA9ICJjb250aW51b3VzIikKY29sb3JzIDwtIGMocGFsWzFdLCBwYWxbMl0sICIjRkZGRkZGIiwgcGFsWzNdLCBwYWxbNF0sIHBhbFs1XSwgcGFsWzZdLCBwYWxbN10sIHBhbFs4XSkKCiNhcnJpdmFscwpSVklfYXJyaXZhbF9wbG90IDwtIGdncGxvdChkYXRhID0gUlZJX2Fycml2YWxfbm9sYWcsIGFlcyh4PXR5cGUsIHkgPSB2YWx1ZSwgZmlsbCA9IHZhcmlhYmxlKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMCwgd2lkdGggPSAwLjgpICsKICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcyA9IGMoIkRlcHRoIiwgIlRyYW5zZm9ybWF0aW9uIiwgIk1ldHJpYyIpLCBsYWJlbHMgPSBjKCJEZXB0aCIsICJUcmFuc2Zvcm1hdGlvbiIsICJNZXRyaWMiKSkgKwogIGxhYnMoeCA9ICJUZW1wZXJhdHVyZSBWYXJpYWJsZXMiLCB5ID0gIlJlbGF0aXZlIFZhcmlhYmxlIEltcG9ydGFuY2UiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMS41KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLnNwYWNpbmcueCA9IHVuaXQoMC4yLCAnY20nKSwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9ICJjZW50ZXIiLAogICAgICAgIGFzcGVjdC5yYXRpbyA9ICgxKSwKICAgICAgICAjLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIKICAgICAgICApICsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQobmNvbD0zKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9ycywKICAgICAgICAgICAgICAgICAgICBkcm9wID0gRikKCiNkZXBhcnR1cmUKUlZJX2RlcGFydHVyZV9wbG90IDwtIGdncGxvdChkYXRhID0gUlZJX2RlcGFydHVyZV9ub2xhZywgYWVzKHg9dHlwZSwgeSA9IHZhbHVlLCBmaWxsID0gdmFyaWFibGUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLCB3aWR0aCA9IDAuOCkgKwogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gYygiRGVwdGgiLCAiVHJhbnNmb3JtYXRpb24iLCAiTWV0cmljIiksIGxhYmVscyA9IGMoIkRlcHRoIiwgIlRyYW5zZm9ybWF0aW9uIiwgIk1ldHJpYyIpKSArCiAgbGFicyh4ID0gIlRlbXBlcmF0dXJlIFZhcmlhYmxlcyIsIHkgPSAiUmVsYXRpdmUgVmFyaWFibGUgSW1wb3J0YW5jZSIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLjUpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBsZWdlbmQuc3BhY2luZy54ID0gdW5pdCgwLjIsICdjbScpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gImNlbnRlciIsCiAgICAgICAgYXNwZWN0LnJhdGlvID0gKDEpLAogICAgICAgICMsIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICAgICAgICkgKwogIGd1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZChuY29sPTMpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JzLAogICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGKQoKUlZJX3RhYmxlClJWSV9hcnJpdmFsX3Bsb3QKUlZJX2RlcGFydHVyZV9wbG90CmBgYAoKTmV4dCBzdGVwIGlzIHRvIGFkZCB0aGUgY29lZmZpY2llbnRzIG9uIHRvIHRoZSBiYXIgY2hhcnQuIFRvIGRvIHRoaXMsIEkgd2lsbCBuZWVkIHRvIHN1bSAoYWlrYWtlIHdlaWdodCBvZiBtb2RlbCBpbmNsdWRpbmcgdmFyaWFibGUgeCBjb2VmZmljaWVudCkuIEkgdGhpbmsgdGhpcyB3aWxsIGJlIGVhc3kgZW5vdWdoIFVzaW5nIGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW4gZGF0YSBmcmFtZS4gSSB3aWxsIGFkZCBuZXcgY29sdW1uIHRvIGRhdGEgZnJhbWUgb2YgYWlrYWlrZSB3ZWlnaHQgeCBjb2VmZmljaWVudAoKYGBge3IgYXZnIGNvZWZmaWNpZW50cyBmb3IgYXJyaXZhbCBtb2RlbHN9CiNmb3Igc29tZSByZWFzb24gdGhlIGNvZWZmaWNpZW50IGlzIGEgZmFjdG9yCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bLGNvZWZfbnVtIDo9IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNvZWYpKV0KYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhblssYXdfY29lZiA6PSBha2Fpa2Vfd2VpZ2h0ICogY29lZl9udW1dCgojYm90dG9tIHRlbXBlcmF0dXJlIGF2ZyBjb2VmZmljaWVudAphcnJpdmFsX2JvdHRvbV90ZW1wX2F2Z19jb2VmIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoInNidCIsIHZhcmlhYmxlKV0kY29lZl9udW0pCgojc3VyZmFjZSB0ZW1wZXJhdHVyZSBhdmcgY29lZmZpY2llbnQKYXJyaXZhbF9zdXJmYWNlX3RlbXBfYXZnX2NvZWYgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic3N0IiwgdmFyaWFibGUpXSRjb2VmX251bSkKCiNyYXcgc2Vhc29uYWxpdHkgYXZnIGNvZWZmaWNpZW50CmFycml2YWxfc2Vhc19yYXdfYXZnX2NvZWYgPC0gCiAgc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic2VhcyIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiY2hhbmdlIiwgdmFyaWFibGUpXSRjb2VmX251bSkKCiNtYXggYWJzIGNoYW5nZSBhdmcgY29lZmZpY2llbnQKYXJyaXZhbF9tYXhfYWJzX2NoYW5nZV9hdmdfY29lZiA8LSAKICBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX25vbWVhbltncmVwKCJtYXhfcy50X3RlbXBfY2hhbmdlX2FicyIsIHZhcmlhYmxlKSwgXSRjb2VmX251bSkKCgpgYGAKCmBgYHtyIGF2ZyBjb2VmZmljaWVudHMgZm9yIGRlcGFydHVyZSBtb2RlbHN9CiNmb3Igc29tZSByZWFzb24gdGhlIGNvZWZmaWNpZW50IGlzIGEgZmFjdG9yCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX25vbWVhblssY29lZl9udW0gOj0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoY29lZikpXQpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bLGF3X2NvZWYgOj0gYWthaWtlX3dlaWdodCAqIGNvZWZfbnVtXQoKI2JvdHRvbSB0ZW1wZXJhdHVyZSBhdmcgY29lZmZpY2llbnQKZGVwYXJ0dXJlX2JvdHRvbV90ZW1wX2F2Z19jb2VmIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic2J0IiwgdmFyaWFibGUpXSRjb2VmX251bSkKCiNzdXJmYWNlIHRlbXBlcmF0dXJlIGF2ZyBjb2VmZmljaWVudApkZXBhcnR1cmVfc3VyZmFjZV90ZW1wX2F2Z19jb2VmIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic3N0IiwgdmFyaWFibGUpXSRjb2VmX251bSkKCiNyYXcgc2Vhc29uYWxpdHkgYXZnIGNvZWZmaWNpZW50CmRlcGFydHVyZV9zZWFzX3Jhd19hdmdfY29lZiA8LSAKICBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fbm9tZWFuW2dyZXAoInNlYXMiLCB2YXJpYWJsZSksIF1bIWdyZXAoImNoYW5nZSIsIHZhcmlhYmxlKV0kY29lZl9udW0pCgojbWluIGNoYW5nZSBhdmcgY29lZmZpY2llbnQKZGVwYXJ0dXJlX21pbl9hYnNfY2hhbmdlX2F2Z19jb2VmIDwtIAogIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgibWluX3MudF90ZW1wX2NoYW5nZSIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiYWJzIiwgdmFyaWFibGUpXSRjb2VmX251bSkKCiNzZWFzIGNoYW5nZSBhdmcgY29lZmZpY2llbnQKZGVwYXJ0dXJlX3NlYXNfY2hhbmdlX2F2Z19jb2VmIDwtIAogIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9ub21lYW5bZ3JlcCgic2Vhc19zLnRfdGVtcF9jaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKV0kY29lZl9udW0pCgoKYGBgCgoKKioqKioqKioqKioqKioqKioqKioqKgojI1doYXQgaWYgd2UgcnVuIHRoZXNlIG1vZGVscyB3aXRoIGZpc2ggb25seT8gTm8gdHJhaXRzPyBIb3cgZG8gaW52ZXJ0cyBjaGFuZ2UgdGhlIHN0b3J5PyBCZWNhdXNlIGl0IGxvb2tzIGxpa2UgYWJvdmUsIG5vdCBhIHRvbiBvZiBpbnZlcnRlYnJhdGVzIGFyZSBnb2luZyBpbiBhbmQgb3V0LiAKCmBgYHtyIGZpc2ggb25seX0KI2xpc3Qgb2YgZmlzaCBuYW1lcyBmcm9tIHRyYWl0IGRhdGFiYXNlCnRyYWl0cyA8LSBmcmVhZCgiVHJhaXRDb2xsZWN0aW9uRmlzaE5BdGxhbnRpY05FUGFjaWZpY0NvbnRTaGVsZiAoMykuY3N2IikKCiNtYWtlIGZpc2ggbm8gZmlzaCBrZXkKZmlzaCA8LSBkYXRhLnRhYmxlKHNwcCA9IHVuaXF1ZSh0cmFpdHMkdGF4b24pLCBmaXNoID0gIlkiKQoKI2NvbWJpbmUgd2l0aCBzcHAgbWFzdGVyCnNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZF9maXNob25seSA8LSBtZXJnZShzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWQsIGZpc2gsIGFsbC54ID0gVCkKCiNnZXQgcmlkIG9mIGFueSByb3dzIHRoYXQgYXJlbid0IG9ic2VydmF0aW9ucyBvZiBmaXNoCnNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZF9maXNob25seTIgPC0gc3BwX21hc3Rlcl96dGVtcF9zZXVzX2J1b3lfc2NhbGVkX2Zpc2hvbmx5W2Zpc2ggPT0gIlkiLF0KCmBgYAoKUnVubmluZyBtb2RlbHMgZm9yIGZpc2ggb25seQoKYGBge3IgYXJyaXZhbCBtb2RlbHMgd2l0aG91dCB0cmFpdHMgZm9yIGZpc2ggb25seX0KCiNuYW1lcyBvZiBzY2FsZWQgY29sdW1ucwpzY2FsZWRfY29scyA8LSBncmVwKCIqX3NjYWxlZCIsIG5hbWVzKHNwcF9tYXN0ZXJfenRlbXBfc2V1c19idW95X3NjYWxlZF9maXNob25seTIpLCB2YWx1ZSA9IFQpCgojZ29pbmcgdG8gbWFrZSBsb29wIHRvIG1ha2UgYWxsIG1vZGVscyBJIG5lZWQgdG8gbG9vayBhdCB3aXRoIHNpbmdsZSB2YXJpYWJsZXMKdmFyaWFibGVzX3NjYWxlZCA8LSBjb2xuYW1lcyhzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWRfZmlzaG9ubHkyWyxzY2FsZWRfY29scywgd2l0aCA9IEZBTFNFXSkKCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5IDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgodmFyaWFibGVzX3NjYWxlZCkpKQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVssIFYxIDo9IE5VTExdCgpmb3IgKGkgaW4gMTpsZW5ndGgodmFyaWFibGVzX3NjYWxlZCkpewogIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQodmFyaWFibGVzX3NjYWxlZFtpXSkgKyAoMXxyZWcpICsgKDF8c3BwKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWRfZmlzaG9ubHkyLCBuQUdRID0gMCkKICBhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVtpLHZhcmlhYmxlIDo9IHZhcmlhYmxlc19zY2FsZWRbaV1dCiAgYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAKICBwcmludChwYXN0ZShpLCBsZW5ndGgodmFyaWFibGVzX3NjYWxlZCksIHNlcCA9ICIvIikpCiAgICAKfQoKI2J5IHNldHRpbmcgbkFDUSB0byAwLCBhbGwgbW9kZWxzIGNvbnZlcmdlZAoKCmBgYAoKZGVwYXJ0dXJlIE1vZGVscyB3aXRob3V0IFRyYWl0cwpgYGB7ciBkZXBhcnR1cmUgbW9kZWxzIHdpdGhvdXQgdHJhaXRzIGZvciBmaXNoIG9ubHl9CiNzZWUgc2V0dXAgYWJvdmUKCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHkgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aCh2YXJpYWJsZXNfc2NhbGVkKSkpCmRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVssIFYxIDo9IE5VTExdCgpmb3IgKGkgaW4gMTpsZW5ndGgodmFyaWFibGVzX3NjYWxlZCkpewogIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KHZhcmlhYmxlc19zY2FsZWRbaV0pICsgKDF8cmVnKSArICgxfHNwcCksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcF9zZXVzX2J1b3lfc2NhbGVkX2Zpc2hvbmx5MiwgbkFHUSA9IDApCiAgZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVtpLHZhcmlhYmxlIDo9IHZhcmlhYmxlc19zY2FsZWRbaV1dCiAgZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICBkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5W2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogIGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAKICBwcmludChwYXN0ZShpLCBsZW5ndGgodmFyaWFibGVzX3NjYWxlZCksIHNlcCA9ICIvIikpCiAgICAKfQoKI2J5IHNldHRpbmcgbkFDUSB0byAwLCBhbGwgbW9kZWxzIGNvbnZlcmdlZAoKCmBgYAoKUmVsYXRpdmUgVmFyaWFibGUgSW1wb3J0YW5jZQpgYGB7ciBnZXQgcmlkIG9mIGFueSBtb2RlbHMgdXNpbmcgbWVhbiBmb3IgZmlzaCBvbmx5fQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW4gPC0gYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlbIWdyZXBsKCJtZWFuIix2YXJpYWJsZSksXQoKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW4gPC0gZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seVshZ3JlcGwoIm1lYW4iLHZhcmlhYmxlKSxdCgojY29tcGFyaXNvbiB0byBudWxsCmNvbF9tb2RfbnVsbCA8LSBnbG1lcihjb2wgfiAoMXxyZWcpICsgKDF8c3BwKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWRfZmlzaG9ubHkyLCBuQUdRID0gMCkKQUlDYyhjb2xfbW9kX251bGwpLW1pbihhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW4kQUlDYykKCmV4dF9tb2RfbnVsbCA8LSBnbG1lcihleHQgfiAoMXxyZWcpICsgKDF8c3BwKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wX3NldXNfYnVveV9zY2FsZWRfZmlzaG9ubHkyLCBuQUdRID0gMCkKQUlDYyhleHRfbW9kX251bGwpLW1pbihkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbiRBSUNjKQpgYGAKClJlbGF0aXZlIFZhcmlhYmxlIEltcG9ydGFuY2UgZm9yIGFycml2YWwgTW9kZWxzCmBgYHtyIFJWSSBhcnJpdmFsIGZvciBmaXNoIG9ubHl9CiNhZGQg4oiGQUlDIHRvIHRhYmxlcwptaW5fY29sX0FJQ2NfZmlzaG9ubHkgPC0gbWluKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblssIEFJQ2NdKQphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bLCJkZWx0YUFJQ2MiIDo9IChBSUNjIC0gbWluX2NvbF9BSUNjX2Zpc2hvbmx5KV0KCiNhZGQgcmVsYXRpdmUgbGlrZWxpaG9vZCBleHAoIC0wLjUgKiDiiIZBSUMgc2NvcmUgZm9yIHRoYXQgbW9kZWwpCmFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblssInJlbF9saWtlbGlob29kIiA6PSBleHAoKC0wLjUgKiBkZWx0YUFJQ2MpKV0KI3N1bSByZWxhdGl2ZSBsaWtlbGlob29kcyBhY3Jvc3MgYWxsIG1vZGVscwphcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW4ubGlrZWxpaG9vZHN1bSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuWywgcmVsX2xpa2VsaWhvb2RdKQojQWthaWtlIHdlaWdodCBmb3IgYSBtb2RlbCBpcyB0aGlzIHJlbF9saWtlbGlob29kIGRldmlkZWQgYnkgdGhlIHN1bSBvZiB0aGVzZSB2YWx1ZXMgYWNyb3NzIGFsbCBtb2RlbHMKYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuWywiYWthaWtlX3dlaWdodCIgOj0gcmVsX2xpa2VsaWhvb2QvYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuLmxpa2VsaWhvb2RzdW1dCgojSSB3YW50IHRvIGxvb2sgYXQgcmVsYXRpdmUgaW1wb3J0YW5jZSBGT1IgCiNib3R0b20vc3VyZmFjZSAoYm90dG9tID0gaW5jbHVkZXMgc2J0LCBncmVwbCgic2J0IiwgdmFyaWFibGUpKQpjb2xfYm90dG9tX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJzYnQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKY29sX3N1cmZhY2VfaW1wb3J0YW5jZV9maXNob25seSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoInNzdCIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2xhZy9ub3QgbGFnZ2VkIChncmVwbCgibGFnIiwgdmFyaWFibGUpKQpjb2xfbGFnX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKY29sX25vbGFnX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblshZ3JlcCgibGFnIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgojYWJzb2x1dGUgKGdyZXBsKCJhYnMiLCB2YXJpYWJsZSkpCmNvbF9hYnNfaW1wb3J0YW5jZV9maXNob25seSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImFicyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI3JhdyAoIWdyZXBsKCJjaGFuZ2UiKSkKY29sX3Jhd19pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bIWdyZXAoImNoYW5nZSIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2NoYW5nZSAoZ3JlcGwoImNoYW5nZSIsIHZhcmlhYmxlKSwgKCFncmVwbCgiYWJzIikpKQpjb2xfY2hhbmdlX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJjaGFuZ2UiLCB2YXJpYWJsZSksIF1bIWdyZXAoImFicyIsIHZhcmlhYmxlKSxdJGFrYWlrZV93ZWlnaHQpCgojdHlwZSBvZiB0ZW1wIHZhcmlhYmxlIChtYXgsIG1pbiwgc2VhcykKY29sX21heF90ZW1wX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJtYXgiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKY29sX21pbl90ZW1wX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJtaW4iLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKY29sX3NlYXNfdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bZ3JlcCgic2VhcyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpgYGAKClJlbGF0aXZlIFZhcmlhYmxlIEltcG9ydGFuY2UgZm9yIGRlcGFydHVyZSBNb2RlbHMKYGBge3IgUlZJIGRlcGFydHVyZSBmb3IgZmlzaCBvbmx5fQojYWRkIOKIhkFJQyB0byB0YWJsZXMKbWluX2V4dF9BSUNjX2Zpc2hvbmx5IDwtIG1pbihkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblssIEFJQ2NdKQpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblssImRlbHRhQUlDYyIgOj0gKEFJQ2MgLSBtaW5fZXh0X0FJQ2NfZmlzaG9ubHkpXQoKI2FkZCByZWxhdGl2ZSBsaWtlbGlob29kIGV4cCggLTAuNSAqIOKIhkFJQyBzY29yZSBmb3IgdGhhdCBtb2RlbCkKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bLCJyZWxfbGlrZWxpaG9vZCIgOj0gZXhwKCgtMC41ICogZGVsdGFBSUNjKSldCiNzdW0gcmVsYXRpdmUgbGlrZWxpaG9vZHMgYWNyb3NzIGFsbCBtb2RlbHMKZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW4ubGlrZWxpaG9vZHN1bSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bLCByZWxfbGlrZWxpaG9vZF0pCiNBa2Fpa2Ugd2VpZ2h0IGZvciBhIG1vZGVsIGlzIHRoaXMgcmVsX2xpa2VsaWhvb2QgZGV2aWRlZCBieSB0aGUgc3VtIG9mIHRoZXNlIHZhbHVlcyBhY3Jvc3MgYWxsIG1vZGVscwpkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhblssImFrYWlrZV93ZWlnaHQiIDo9IHJlbF9saWtlbGlob29kL2RlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuLmxpa2VsaWhvb2RzdW1dCgojSSB3YW50IHRvIGxvb2sgYXQgcmVsYXRpdmUgaW1wb3J0YW5jZSBGT1IgCiNib3R0b20vc3VyZmFjZSAoYm90dG9tID0gaW5jbHVkZXMgc2J0LCBncmVwbCgic2J0IiwgdmFyaWFibGUpKQpleHRfYm90dG9tX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoInNidCIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpleHRfc3VyZmFjZV9pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJzc3QiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNsYWcvbm90IGxhZ2dlZCAoZ3JlcGwoImxhZyIsIHZhcmlhYmxlKSkKZXh0X2xhZ19pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZXh0X25vbGFnX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuWyFncmVwKCJsYWciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNhYnNvbHV0ZSAoZ3JlcGwoImFicyIsIHZhcmlhYmxlKSkKZXh0X2Fic19pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJhYnMiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKCiNyYXcgKCFncmVwbCgiY2hhbmdlIikpCmV4dF9yYXdfaW1wb3J0YW5jZV9maXNob25seSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bIWdyZXAoImNoYW5nZSIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQoKI2NoYW5nZSAoZ3JlcGwoImNoYW5nZSIsIHZhcmlhYmxlKSwgKCFncmVwbCgiYWJzIikpKQpleHRfY2hhbmdlX2ltcG9ydGFuY2VfZmlzaG9ubHkgPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImNoYW5nZSIsIHZhcmlhYmxlKSwgXVshZ3JlcCgiYWJzIiwgdmFyaWFibGUpLF0kYWthaWtlX3dlaWdodCkKCiN0eXBlIG9mIHRlbXAgdmFyaWFibGUgKG1heCwgbWluLCBzZWFzKQpleHRfbWF4X3RlbXBfaW1wb3J0YW5jZV9maXNob25seSA8LSBzdW0oZGVwYXJ0dXJlX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bZ3JlcCgibWF4IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmV4dF9taW5fdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJtaW4iLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKZXh0X3NlYXNfdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5IDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJzZWFzIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmBgYAoKTGV0J3Mgc2VlIGhvdyB0aGUgUlZJIGltcG9ydGFuY2UgdmFyaWVzIGJ5IGxvb2tpbmcgYXQgc3BlY2lmaWMgbGFnIHZhbHVlcwpgYGB7ciBtYWtlIGEgcGxvdCBoZXJlIGZvciB2YXJpYWJpbGl0eSBhY3Jvc3MgbGFnIHZhbHVlcyBmb3IgZmlzaCBvbmx5fQojZmlyc3QsIHRhYmxlIGZvciBsYWdzCmxhZ3Nfdl9SVklfc3BwcmFuZG9tX3NjYWxlZF9maXNob25seSA8LSBkYXRhLnRhYmxlKGNvbF9sYWcgPSBjKDA6OSksIGNvbF9SVkkgPSAwLCBkZXBhcnR1cmVfUlZJID0gMCkKI2Fycml2YWwKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzEsMl0gPC0gMS1zdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX3ZfUlZJX3NwcHJhbmRvbV9zY2FsZWRfZmlzaG9ubHlbMiwyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzEiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzMsMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWcyIiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3Nfdl9SVklfc3BwcmFuZG9tX3NjYWxlZF9maXNob25seVs0LDJdIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bZ3JlcCgibGFnMyIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX3ZfUlZJX3NwcHJhbmRvbV9zY2FsZWRfZmlzaG9ubHlbNSwyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzYsMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWc1IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3Nfdl9SVklfc3BwcmFuZG9tX3NjYWxlZF9maXNob25seVs3LDJdIDwtIHN1bShhcnJpdmFsX21vZGVsX2NvbXBhcmlzb25fc3BwcmFuZG9tX3NjYWxlZF9zZXVzX3VwZGF0ZV9maXNob25seV9ub21lYW5bZ3JlcCgibGFnNiIsIHZhcmlhYmxlKSwgXSRha2Fpa2Vfd2VpZ2h0KQpsYWdzX3ZfUlZJX3NwcHJhbmRvbV9zY2FsZWRfZmlzaG9ubHlbOCwyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzksMl0gPC0gc3VtKGFycml2YWxfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWc4IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCmxhZ3Nfdl9SVklfc3BwcmFuZG9tX3NjYWxlZF9maXNob25seVsxMCwyXSA8LSBzdW0oYXJyaXZhbF9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzkiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKI2RlcGFydHVyZQpsYWdzX3ZfUlZJX3NwcHJhbmRvbV9zY2FsZWRfZmlzaG9ubHlbMSwzXSA8LSAxLXN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzIsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzEiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzMsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzIiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzQsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzMiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzUsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzQiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzYsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzUiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzcsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzYiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzgsM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzciLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzksM10gPC0gc3VtKGRlcGFydHVyZV9tb2RlbF9jb21wYXJpc29uX3NwcHJhbmRvbV9zY2FsZWRfc2V1c191cGRhdGVfZmlzaG9ubHlfbm9tZWFuW2dyZXAoImxhZzgiLCB2YXJpYWJsZSksIF0kYWthaWtlX3dlaWdodCkKbGFnc192X1JWSV9zcHByYW5kb21fc2NhbGVkX2Zpc2hvbmx5WzEwLDNdIDwtIHN1bShkZXBhcnR1cmVfbW9kZWxfY29tcGFyaXNvbl9zcHByYW5kb21fc2NhbGVkX3NldXNfdXBkYXRlX2Zpc2hvbmx5X25vbWVhbltncmVwKCJsYWc5IiwgdmFyaWFibGUpLCBdJGFrYWlrZV93ZWlnaHQpCgpnZ3Bsb3QoZGF0YSA9IGxhZ3Nfdl9SVklfc3BwcmFuZG9tX3NjYWxlZF9maXNob25seSwgYWVzKHggPSBjb2xfbGFnKSkgKwogIGdlb21fbGluZShhZXMoeSA9IGNvbF9SVkkpLCBjb2wgPSAiYmx1ZSIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBkZXBhcnR1cmVfUlZJKSwgY29sID0gInJlZCIpICsKICBsYWJzKHggPSAiTGFnIiwgeSA9ICJSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIikgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKCkgKyAjaG93IHRvIG1ha2UgYSBsZWdlbmQKICB0aGVtZV9idygpCmBgYAoKVGFibGUgZm9yIFJWSSBkYXRhIGZvciBhcnJpdmFsCmBgYHtyIHB1dCBSVklzIGZvciBhcnJpdmFsIGludG8gZGF0YSB0YWJsZSBmb3IgZmlzaCBvbmx5fQpjb2xfZXh0IDwtIGMoImNvbCIsImNvbCIsImNvbCIsImNvbCIsImNvbCIsICJjb2wiLCJjb2wiLCAiY29sIiwgImNvbCIsImNvbCIpCnR5cGUgPC0gYygiZGVwdGgiLCAiZGVwdGgiLCAibGFnIiwgImxhZyIsICJDaGFuZ2U/IiwgIkNoYW5nZT8iLCAiQ2hhbmdlPyIsICJUZW1wIiwgIlRlbXAiLCAiVGVtcCIpCnZhcmlhYmxlIDwtIGMoImJvdHRvbSIsICJzdXJmYWNlIiwgIm5vX2xhZyIsICJsYWdnZWQiLCAiYWJzb2x1dGVfdmFsdWVfY2hhbmdlIiwgImNoYW5nZSIsICJyYXciLCAiTWluIiwgIk1heCIsICJTZWFzIikKdmFsdWUgPC0gYyhjb2xfYm90dG9tX2ltcG9ydGFuY2VfZmlzaG9ubHksIGNvbF9zdXJmYWNlX2ltcG9ydGFuY2VfZmlzaG9ubHksIGNvbF9ub2xhZ19pbXBvcnRhbmNlX2Zpc2hvbmx5LCBjb2xfbGFnX2ltcG9ydGFuY2VfZmlzaG9ubHksIGNvbF9hYnNfaW1wb3J0YW5jZV9maXNob25seSwgY29sX2NoYW5nZV9pbXBvcnRhbmNlX2Zpc2hvbmx5LCBjb2xfcmF3X2ltcG9ydGFuY2VfZmlzaG9ubHksIGNvbF9taW5fdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5LCBjb2xfbWF4X3RlbXBfaW1wb3J0YW5jZV9maXNob25seSwgY29sX3NlYXNfdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5KQoKUlZJX2NvbF9maXNob25seSA8LSBkYXRhLnRhYmxlKGNvbF9leHQsIHR5cGUsIHZhcmlhYmxlLCB2YWx1ZSkKYGBgCgpUYWJsZSBmb3IgUlZJIGRhdGEgZm9yIGRlcGFydHVyZQpgYGB7ciBwdXQgUlZJcyBmb3IgZGVwYXJ0dXJlIGludG8gZGF0YSB0YWJsZSBmb3IgZmlzaCBvbmx5fQpjb2xfZXh0IDwtIGMoImV4dCIsImV4dCIsImV4dCIsImV4dCIsImV4dCIsICJleHQiLCAiZXh0IiwgImV4dCIsICJleHQiLCAiZXh0IikKdHlwZSA8LSBjKCJkZXB0aCIsICJkZXB0aCIsICJsYWciLCAibGFnIiwgIkNoYW5nZT8iLCAiQ2hhbmdlPyIsICJDaGFuZ2U/IiwgIlRlbXAiLCAiVGVtcCIsICJUZW1wIikKdmFyaWFibGUgPC0gYygiYm90dG9tIiwgInN1cmZhY2UiLCAibm9fbGFnIiwgImxhZ2dlZCIsICJhYnNvbHV0ZV92YWx1ZV9jaGFuZ2UiLCAiY2hhbmdlIiwgInJhdyIsICJNaW4iLCAiTWF4IiwgIlNlYXMiKQp2YWx1ZSA8LSBjKGV4dF9ib3R0b21faW1wb3J0YW5jZV9maXNob25seSwgZXh0X3N1cmZhY2VfaW1wb3J0YW5jZV9maXNob25seSwgZXh0X25vbGFnX2ltcG9ydGFuY2VfZmlzaG9ubHksIGV4dF9sYWdfaW1wb3J0YW5jZV9maXNob25seSwgZXh0X2Fic19pbXBvcnRhbmNlX2Zpc2hvbmx5LCBleHRfY2hhbmdlX2ltcG9ydGFuY2VfZmlzaG9ubHksIGV4dF9yYXdfaW1wb3J0YW5jZV9maXNob25seSwgZXh0X21pbl90ZW1wX2ltcG9ydGFuY2VfZmlzaG9ubHksIGV4dF9tYXhfdGVtcF9pbXBvcnRhbmNlX2Zpc2hvbmx5LCBleHRfc2Vhc190ZW1wX2ltcG9ydGFuY2VfZmlzaG9ubHkpCgpSVklfZXh0X2Zpc2hvbmx5IDwtIGRhdGEudGFibGUoY29sX2V4dCwgdHlwZSwgdmFyaWFibGUsIHZhbHVlKQpgYGAKCk1lcmdlIFJWSSB0YWJsZXMgZm9yIGFycml2YWwgYW5kIGRlcGFydHVyZSwgYW5kIHRoZW4gZ3JhcGgKYGBge3IgbWVyZ2UgUlZJIHRhYmxlcyBhbmQgcGxvdCBmb3IgZmlzaCBvbmx5fQpSVklfdGFibGVfZmlzaG9ubHkgPC0gYXMuZGF0YS50YWJsZShyYmluZChSVklfY29sX2Zpc2hvbmx5LCBSVklfZXh0X2Zpc2hvbmx5KSkgI2JpbmQgUlZJIGZvciBhcnJpdmFscyBhbmQgZGVwYXJ0dXJlcwoKUlZJX3RhYmxlLnJfZmlzaG9ubHkgPC0gUlZJX3RhYmxlX2Zpc2hvbmx5WyFncmVwKCJzdXJmYWNlIiwgdmFyaWFibGUpXVshZ3JlcCgibGFnZ2VkIiwgdmFyaWFibGUpXQoKI2NoYW5nZSBvcmRlciBvZiBmYWN0b3IgbGV2ZWxzClJWSV90YWJsZS5yX2Zpc2hvbmx5WywgdmFyaWFibGUgOj0gZmFjdG9yKHZhcmlhYmxlLCBsZXZlbHMgPSBjKCJib3R0b20iLCAibm9fbGFnIiwgInJhdyIsICJjaGFuZ2UiLCAiYWJzb2x1dGVfdmFsdWVfY2hhbmdlIiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpKV0KCnNhdmUoUlZJX3RhYmxlX2Zpc2hvbmx5LCBmaWxlID0gIlJWSV90YWJsZV9maXNob25seS5SZGF0YSIpCgpnZ3Bsb3QoZGF0YSA9IFJWSV90YWJsZS5yX2Zpc2hvbmx5LCBhZXMoeD12YXJpYWJsZSwgeSA9IHZhbHVlLCBmaWxsID0gY29sX2V4dCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3MgPSBjKCJib3R0b20iLCAibm9fbGFnIiwgInJhdyIsICJjaGFuZ2UiLCAiYWJzb2x1dGVfdmFsdWVfY2hhbmdlIiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpLCBsYWJlbHMgPSBjKCJCb3R0b20gVGVtcCIsICJObyBMYWciLCAiUmF3IFRlbXAiLCAiQ2hhbmdlIGluIFxuVGVtcCIsICJ8IENoYW5nZSBpblxuIFRlbXAgfCIsICJNaW4gVGVtcCIsICJNYXggVGVtcCIsICJTZWFzIikpICsKICBsYWJzKHggPSAiVGVtcGVyYXR1cmUgVmFyaWFibGVzIiwgeSA9ICJSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIikgICsKICB0aGVtZV9idygpCgpgYGAKCkFub3RoZXIgd2F5IHRvIHZpc3VhbGl6ZSBpcyBzdGFja2VkIGJhciBwbG90LgoKYGBge3IgUlZJIHN0YWNrZWQgcGxvdCBmb3IgZmlzaCBvbmx5fQojcHV0IGxldmVscyBpbnRvIGNvcnJlY3Qgb3JkZXIgZm9yIHZpZXdpbmcKUlZJX3RhYmxlX2Zpc2hvbmx5WywgdmFyaWFibGUgOj0gZmFjdG9yKHZhcmlhYmxlLCBsZXZlbHMgPSBjKCJib3R0b20iLCAic3VyZmFjZSIsICJhYnNvbHV0ZV92YWx1ZV9jaGFuZ2UiLCAiY2hhbmdlIiwgInJhdyIsICJub19sYWciLCAibGFnZ2VkIiwgIk1pbiIsICJNYXgiLCAiU2VhcyIpKV0KI21ha2UgdHlwZXMgZmFjdG9ycyBhcyB3ZWxsClJWSV90YWJsZV9maXNob25seVssdHlwZSA6PSBhcy5mYWN0b3IodHlwZSldCgojYXJyaXZhbApSVklfY29sX3Bsb3RfZmlzaG9ubHkgPC0gZ2dwbG90KGRhdGEgPSBSVklfdGFibGVfZmlzaG9ubHlbY29sX2V4dCA9PSAiY29sIixdLCBhZXMoeD10eXBlLCB5ID0gdmFsdWUsIGZpbGwgPSB2YXJpYWJsZSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gYygiQ2hhbmdlPyIsICJkZXB0aCIsICJsYWciLCAiVGVtcCIpLCBsYWJlbHMgPSBjKCJDaGFuZ2UgaW5cbnRlbXA/IiwgIk1ldHJpY1xuRGVwdGgiLCAiTGFnZ2VkPyIsICJUZW1wIikpICsKICBsYWJzKHggPSAiVGVtcGVyYXR1cmUgVmFyaWFibGVzIiwgeSA9ICJSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjIpCiAgICAgICAgIywgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiCiAgICAgICAgKQoKI2RlcGFydHVyZQpSVklfZXh0X3Bsb3RfZmlzaG9ubHkgPC0gZ2dwbG90KGRhdGEgPSBSVklfdGFibGVfZmlzaG9ubHlbY29sX2V4dCA9PSAiZXh0IixdLCBhZXMoeD10eXBlLCB5ID0gdmFsdWUsIGZpbGwgPSB2YXJpYWJsZSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gYygiQ2hhbmdlPyIsICJkZXB0aCIsICJsYWciLCAiVGVtcCIpLCBsYWJlbHMgPSBjKCJDaGFuZ2UgaW5cbnRlbXA/IiwgIk1ldHJpY1xuRGVwdGgiLCAiTGFnZ2VkPyIsICJUZW1wIikpICsKICBsYWJzKHggPSAiVGVtcGVyYXR1cmUgVmFyaWFibGVzIiwgeSA9ICJSZWxhdGl2ZSBWYXJpYWJsZSBJbXBvcnRhbmNlIikgKwogIHRoZW1lX2NsYXNzaWMoKSAgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIyKQogICAgICAgICMsIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICAgICAgICkKClJWSV90YWJsZV9maXNob25seQpSVklfY29sX3Bsb3RfZmlzaG9ubHkKUlZJX2V4dF9wbG90X2Zpc2hvbmx5CgoKYGBgCgo=